@hyperfrontend/project-scope/nxNX Module
The nx module provides utilities for detecting and working with NX workspaces. It supports NX monorepo detection, workspace configuration reading, project enumeration, and optional @nx/devkit integration.
Capabilities
Workspace Detection
Detect if a directory is an NX workspace.
import { isNxWorkspace, findNxWorkspaceRoot, isNxProject } from '@hyperfrontend/project-scope'
// Check if current directory is NX workspace root
if (isNxWorkspace('./my-monorepo')) {
console.log('This is an NX workspace')
}
// Find workspace root from any nested path
const root = findNxWorkspaceRoot('./libs/my-lib/src/utils')
console.log('Workspace root:', root) // '/home/user/my-monorepo'
// Check if directory is an NX project (has project.json)
if (isNxProject('./libs/my-lib')) {
console.log('This is an NX project')
}
Workspace Information
Get comprehensive workspace details.
import { getNxWorkspaceInfo } from '@hyperfrontend/project-scope'
const info = getNxWorkspaceInfo('./my-monorepo')
console.log('Root:', info.root)
console.log('NX Version:', info.version) // '17.2.0'
console.log('Integrated:', info.isIntegrated) // true
console.log('Default project:', info.defaultProject)
console.log('Layout:', info.workspaceLayout) // { appsDir: 'apps', libsDir: 'libs' }
console.log('NX JSON:', info.nxJson) // Full nx.json content
Project Configuration
Read and parse NX project configuration.
import { readNxProjectConfig, findNxProjects } from '@hyperfrontend/project-scope'
// Read single project config
const config = readNxProjectConfig('./libs/my-lib')
console.log('Name:', config.name)
console.log('Type:', config.projectType) // 'library' | 'application'
console.log('Source root:', config.sourceRoot)
console.log('Tags:', config.tags)
console.log('Targets:', Object.keys(config.targets ?? {}))
// Find all projects in workspace
const projects = findNxProjects('./my-monorepo')
for (const project of projects) {
console.log(`${project.name} (${project.projectType})`)
}
@nx/devkit Integration
Optional integration with @nx/devkit for enhanced functionality.
import { isDevkitAvailable, getDevkit, tryLoadDevkit, withDevkit } from '@hyperfrontend/project-scope'
// Check availability
if (isDevkitAvailable()) {
const devkit = getDevkit()
// Use devkit APIs directly
}
// Graceful fallback pattern
const tree = withDevkit(
(devkit) => devkit.createTreeWithEmptyWorkspace(),
() => createTree(process.cwd())
)
// Detailed load result
const result = tryLoadDevkit()
if (result.available) {
console.log('Devkit loaded:', result.devkit)
} else {
console.log('Devkit error:', result.error)
}
NX Configuration Files
The module detects these NX configuration files:
| File | Description |
|---|---|
nx.json |
Main workspace configuration |
workspace.json |
Legacy workspace configuration |
project.json |
Project-specific configuration |
Interfaces
NxWorkspaceInfo
interface NxWorkspaceInfo {
/** Workspace root path */
root: string
/** NX version from package.json */
version: string | null
/** Parsed nx.json content */
nxJson: NxJson
/** Whether this is an integrated repo */
isIntegrated: boolean
/** Default project name */
defaultProject?: string
/** Workspace layout configuration */
workspaceLayout: NxWorkspaceLayout
}
NxWorkspaceLayout
interface NxWorkspaceLayout {
/** Applications directory (default: 'apps') */
appsDir: string
/** Libraries directory (default: 'libs') */
libsDir: string
}
NxJson
interface NxJson {
defaultProject?: string
workspaceLayout?: Partial<NxWorkspaceLayout>
namedInputs?: Record<string, unknown>
targetDefaults?: Record<string, unknown>
nxCloudAccessToken?: string
plugins?: unknown[]
tasksRunnerOptions?: Record<string, unknown>
defaultBase?: string
[key: string]: unknown
}
Design Principles
- Optional devkit: Works without
@nx/devkitinstalled - Caching: Results are cached appropriately
- Version agnostic: Supports multiple NX versions
- Standalone support: Detects both integrated and standalone repos
- Type safety: Full TypeScript types for all configurations
API Reference
ƒ Functions
buildSimpleProjectGraph(workspacePath: string, projects?: Map<string, NxProjectConfig>): NxProjectGraph
@nx/devkit.Parameters
Returns
NxProjectGraphExample
Building a simple project graph
import { buildSimpleProjectGraph } from '@hyperfrontend/project-scope'
const graph = buildSimpleProjectGraph('/workspace')
console.log('Projects:', Object.keys(graph.nodes))
console.log('Dependencies:', graph.dependencies['my-app'])Parameters
| Name | Type | Description |
|---|---|---|
§workspacePath | string | Workspace root path |
Returns
Map<string, NxProjectConfig>Example
Discovering all NX projects
import { discoverNxProjects } from '@hyperfrontend/project-scope'
const projects = discoverNxProjects('/workspace')
for (const [name, config] of projects) {
console.log(`${name}: ${config.projectType} at ${config.root}`)
}Parameters
| Name | Type | Description |
|---|---|---|
§startPath | string | Starting path to search from |
Returns
stringExample
Finding NX workspace root
import { findNxWorkspaceRoot } from '@hyperfrontend/project-scope'
const root = findNxWorkspaceRoot('./libs/my-lib/src')
if (root) {
console.log('Workspace root:', root) // e.g., '/home/user/my-monorepo'
}@nx/devkit module if available. Throws if not available.Returns
__module@nx/devkit module with full type informationExample
Getting the devkit module
import { getDevkit } from '@hyperfrontend/project-scope'
const devkit = getDevkit()
const projects = devkit.getProjects(tree)Parameters
| Name | Type | Description |
|---|---|---|
§workspacePath | string | Workspace root path |
Returns
NxWorkspaceInfoExample
Getting NX workspace information
import { getNxWorkspaceInfo } from '@hyperfrontend/project-scope'
const info = getNxWorkspaceInfo('/path/to/monorepo')
if (info) {
console.log('NX version:', info.version)
console.log('Apps dir:', info.workspaceLayout.appsDir)
}Parameters
Returns
NxProjectConfigExample
Getting project configuration
import { getProjectConfig } from '@hyperfrontend/project-scope'
const config = getProjectConfig('./libs/my-lib', '/workspace')
// => { name: 'my-lib', root: 'libs/my-lib', projectType: 'library' }@nx/devkit is available.Returns
booleanExample
Checking devkit availability
import { isDevkitAvailable } from '@hyperfrontend/project-scope'
if (isDevkitAvailable()) {
// Use full NX devkit features
} else {
// Fall back to standalone mode
}Parameters
| Name | Type | Description |
|---|---|---|
§path | string | Directory path to check |
Returns
booleanExample
Checking for NX project
import { isNxProject } from '@hyperfrontend/project-scope'
if (isNxProject('./libs/my-lib')) {
console.log('This is an NX project')
}Parameters
| Name | Type | Description |
|---|---|---|
§path | string | Directory path to check |
Returns
booleanExample
Checking for NX workspace
import { isNxWorkspace } from '@hyperfrontend/project-scope'
if (isNxWorkspace('./my-project')) {
console.log('This is an NX monorepo')
}Parameters
| Name | Type | Description |
|---|---|---|
§projectPath | string | Project directory path |
Returns
NxProjectConfigExample
Reading NX project.json
import { readProjectJson } from '@hyperfrontend/project-scope'
const config = readProjectJson('./libs/my-lib')
if (config) {
console.log('Project:', config.name, 'Type:', config.projectType)
}@nx/devkit at runtime. Uses dynamic require to avoid bundling @nx/devkit into our output. Results are cached for subsequent calls.Returns
DevkitLoadResultExample
Loading devkit dynamically
import { tryLoadDevkit } from '@hyperfrontend/project-scope'
const result = tryLoadDevkit()
if (result.available) {
const tree = result.devkit.createTree()
}@nx/devkit if available, otherwise execute fallback. This pattern allows graceful degradation when @nx/devkit is not installed.Parameters
Returns
TExample
Using devkit with fallback
const tree = withDevkit(
(devkit) => devkit.createTree(),
() => new FsTree(process.cwd())
)◈ Interfaces
@nx/devkit.