Skip to content

TypeScript Projects

The TypeScript project generator can be used to create a modern TypeScript library or application configured with best practices such as ECMAScript Modules (ESM), TypeScript project references, Vitest for running tests and ESLint for static analysis.

Usage

Generate a TypeScript Project

You can generate a new TypeScript project in two ways:

  1. Install the Nx Console VSCode Plugin if you haven't already
  2. Open the Nx Console in VSCode
  3. Click Generate (UI) in the "Common Nx Commands" section
  4. Search for @aws/nx-plugin - ts#project
  5. Fill in the required parameters
    • Click Generate

    Options

    Parameter Type Default Description
    name required string - Library name.
    directory string packages Parent directory where the library is placed.
    subDirectory string - The sub directory the lib is placed in. By default this is the library name.

    Generator Output

    The generator will create the following project structure in the <directory>/<name> directory:

    • Directorysrc TypeScript source code
      • index.ts
    • project.json Project configuration and build targets
    • tsconfig.json Base TypeScript configuration for this project (extends workspace root tsconfig.base.json)
    • tsconfig.lib.json TypeScript configuration for your library (your runtime or packaged source)
    • tsconfig.spec.json TypeScript configuration for your tests
    • vite.config.ts Configuration for Vitest
    • eslint.config.mjs Configuration for ESLint

    You will also notice some changes to the following files in your workspace root:

    • nx.json Nx configuration is updated to configure the @nx/js/typescript plugin for your project
    • tsconfig.base.json a TypeScript alias is set up for your project so that it can be imported by other projects in your workspace
    • tsconfig.json a TypeScript project reference is added for your project

    Writing TypeScript Source Code

    Add your TypeScript code in the src directory.

    ESM Import Syntax

    Since your TypeScript project is an ES Module, be sure to write your import statements with the correct ESM syntax, explicitly referencing the file extension:

    index.ts
    import { sayHello } from './hello.js';

    Exporting for Other TypeScript Projects

    The entry point for your TypeScript project is src/index.ts. You can add exports here for anything you’d like other projects to be able to import:

    src/index.ts
    export { sayHello } from './hello.js';
    export * from './algorithms/index.js';

    Importing your Library Code in Other Projects

    TypeScript aliases for your project are configured in your workspace tsconfig.base.json, which allows you to reference your TypeScript project from other TypeScript projects:

    packages/my-other-project/src/index.ts
    import { sayHello } from ':my-scope/my-library';

    When you add an import statement for a new project in your workspace for the first time, you will likely see an error in your IDE similar to the below:

    Import error
    Terminal window
    File '/path/to/my/workspace/packages/my-library/src/index.ts' is not under 'rootDir' '/path/to/my/workspace/packages/my-consumer'. 'rootDir' is expected to contain all source files.
    File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6059)
    File '/path/to/my/workspace/packages/my-library/src/index.ts' is not listed within the file list of project '/path/to/my/workspace/packages/my-consumer/tsconfig.lib.json'. Projects must list all files or use an 'include' pattern.
    File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6307)

    This is because a project reference has not yet been set up.

    TypeScript projects are configured with the Nx TypeScript Sync generator out of the box, saving you from needing to manually configure the project reference. Simply run the following command and Nx will add the required configuration:

    Terminal window
    pnpm nx sync

    After this, the error in your IDE should be gone and you are ready to use your library.

    Dependencies

    You will notice that your TypeScript project does not have a package.json file, which might be unexpected if you are used to traditional TypeScript monorepos.

    To add a dependency for any TypeScript package in your monorepo, simply add the dependency to the package.json in the root of your workspace. You can do this via the command line for your package manager:

    Terminal window
    pnpm add -w some-npm-package

    The dependency is then available for any of the TypeScript projects in your workspace to use.

    Runtime Code

    When you use your TypeScript project as runtime code (for example as the handler for an AWS Lambda function), it’s recommended that you use a tool such as esbuild to bundle your project, since this can tree-shake to ensure that only the dependencies your project actually references are included.

    You can achieve this by adding a target such as the following to your project.json file:

    {
    ...
    "targets": {
    ...
    "bundle": {
    "cache": true,
    "executor": "nx:run-commands",
    "outputs": ["{workspaceRoot}/dist/packages/my-library/bundle"],
    "options": {
    "command": "esbuild packages/my-library/src/index.ts --bundle --outfile=dist/packages/my-library/bundle/index.js --platform=node --format=cjs"
    }
    },
    },
    }

    Publishing to NPM

    If you are publishing your TypeScript project to NPM, you must create a package.json file for it.

    This must declare the dependencies that your project references. Since at build time your project will resolve dependencies installed via the workspace root package.json, it’s recommended to configure the Nx Dependency Checks ESLint Plugin to ensure that your published project’s package.json includes all dependencies you use in your project.

    Building

    Your TypeScript project is configured with a build target (defined in project.json), which you can run via:

    Terminal window
    pnpm nx run <project-name>:build

    Where <project-name> is the fully qualified name of your project.

    The build target will compile, lint and test your project.

    Build output can be found in the root dist folder in your workspace, inside a directory for your package and target, for example dist/packages/<my-library>/tsc

    Testing

    Vitest is configured for testing your project.

    Writing Tests

    Tests should be written in .spec.ts or .test.ts files, co-located in your project’s src folder.

    For example:

    • Directorysrc
      • hello.ts Library source code
      • hello.spec.ts Tests for hello.ts

    Vitest provides Jest-like syntax for defining tests, with utilities such as describe, it, test and expect.

    hello.spec.ts
    import { sayHello } from './hello.js';
    describe('sayHello', () => {
    it('should greet the caller', () => {
    expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!');
    });
    });

    For more details about how to write tests, and features such as mocking dependencies, refer to the Vitest documentation

    Running Tests

    Tests will run as part of the build target for your project, but you can also run them separately by running the test target:

    Terminal window
    pnpm nx run <project-name>:test

    You can run an individual test or suite of tests using the -t flag:

    Terminal window
    pnpm nx run <project-name>:test -t 'sayHello'

    Linting

    TypeScript projects use ESLint for linting, along with Prettier for formatting.

    We recommend configuring ESLint in the workspace root eslint.config.mjs file, as changes to this will apply to all TypeScript projects in your workspace and ensure consistency.

    Likewise, you can configure Prettier in the root .prettierrc file.

    Running the Linter

    To invoke the linter to check your project, you can run the lint target.

    Terminal window
    pnpm nx run <project-name>:lint

    Fixing Lint Issues

    The majority of linting or formatting issues can be fixed automatically. You can tell ESLint to fix lint issues by running with the --configuration=fix argument.

    Terminal window
    pnpm nx run <project-name>:lint --configuration=fix

    Similarly if you would like to fix all lint issues in all packages in your workspace, you can run:

    Terminal window
    pnpm nx run-many --target lint --all --configuration=fix