Skip to main content
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:

project
src
app
cards
Widget.tsx
shared
utils.ts
import { formatData } from '../shared/utils';

function Widget() {
  const data = formatData(props.data);
  return <Text>{data}</Text>;
}
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. If you need to share code between multiple extension points, use npm workspaces:
  1. Create a shared workspace package directory at the root of your project:

project
hsproject.json
packages
shared-utils
package.json
tsconfig.json
src
format.ts
src
app
cards
Widget.tsx
  1. Configure your root package.json:
{
  "name": "my-ui-extensions-app",
  "workspaces": [
    "packages/*"
  ]
}
  1. 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