The no-parent-imports rule prevents importing files from outside the extension point root directory using relative paths.
Rule details
Extension points are self-contained architectural units. Each extension point (e.g., Settings, Pages) is built and deployed independently, which means all code for an extension must live within its root directory. Files outside this boundary are not included when the extension is packaged for deployment.
This rule prevents relative imports (../) that escape your extension point’s directory. While these imports work during local development (when your full project structure is available), they fail at runtime because the referenced files don’t exist in the deployed extension package.
Example
As an example, consider the following project structure:
Because Widget.tsx imports from ../shared/utils.ts, the app card will work locally, as the utils.ts file is available within the development environment. However, once built and deployed, the shared/ directory won’t be included in either the cards/ or settings/ builds, and utils.ts will no longer be available to either one.
Solving with npm workspaces (recommended)
If you need to share code between multiple extension points, use npm workspaces:
- Create a shared workspace
package directory at the root of your project:
- Configure your root
package.json:
{
"name": "my-ui-extensions-app",
"workspaces": [
"packages/*"
]
}
- In your UI extension code, import from the shared package:
// In: src/app/cards/Widget.tsx
import { formatData } from '@my-app/shared-utils'; // ✓ Using workspace package
function Widget() {
const data = formatData(props.data);
return <Text>{data}</Text>;
}
Solving with extension point-specific code
Move shared code into the extension point directory and use relative imports freely:
// In: src/app/cards/Widget.tsx
import { formatData } from './utils/format'; // ✓ Stays within cards directory
function Widget() {
const data = formatData(props.data);
return <Text>{data}</Text>;
}
You can use relative imports anywhere within your extension point:
// In: src/app/cards/components/Widget.tsx
import { useCardData } from '../hooks/useCardData'; // ✓ Stays within cards directory
import { Button } from './Button'; // ✓ Stays within cards directory
function Widget() {
const data = useCardData();
return <Button onClick={() => {}}>{data.title}</Button>;
}
Valid relative import patterns
The following patterns are all valid because they stay within the extension point:
// All in src/app/cards/ directory structure
// From: src/app/cards/components/Widget.tsx
import { util } from './Button'; // ✓ Same directory
import { util } from '../utils'; // ✓ Parent directory, still in cards
import { util } from '../../cards/hooks'; // ✓ Goes up but comes back to cards
Common scenarios
Sharing constants
Instead of importing constants from outside the extension point:
// Incorrect
// src/app/cards/Widget.tsx
import { API_URL } from '../config/constants'; // ❌ Escapes extension point
Define constants within the extension point:
// src/app/cards/constants.ts
export const API_URL = 'https://api.example.com';
// src/app/cards/Widget.tsx
import { API_URL } from './constants'; // ✓ Stays within cards
Sharing utility functions
Instead of importing utilities from outside the extension point:
// Incorrect
// src/app/settings/Config.tsx
import { formatDate } from '../utils/date'; // ❌ Escapes extension point
Use npm workspaces to share utilities across extension points:
// packages/shared-utils/src/date.ts
export const formatDate = (date: Date) => { /* ... */ };
// src/app/settings/Config.tsx
import { formatDate } from '@my-app/shared-utils'; // ✓ Using workspace
Sharing types/interfaces
Instead of importing types from outside the extension point:
// Incorrect
// src/app/cards/Widget.tsx
import type { UserData } from '../../types/user'; // ❌ Escapes extension point
Use npm workspaces to share types across extension points:
// packages/shared-types/src/user.ts
export interface UserData { /* ... */ }
// src/app/cards/Widget.tsx
import type { UserData } from '@my-app/shared-types'; // ✓ Using workspace
Last modified on February 19, 2026