GitHub - niedzielski/node-ts-template: Running TypeScript in Node.js without any extra tooling.

3 min read Original article ↗

Node.js TypeScript Template

Using TypeScript in Node.js with minimal dependencies and no compilation. Node.js previously only supported plain JavaScript. Since v22.6.0, experimental type-stripping support was added to enable TypeScript natively for imports, executables, and even the built-in test runner.

Pros

  • No production dependencies and minimal development dependencies.
  • No compilation.
  • The same language everywhere: server code, client code, tests, and tools. No errorprone shell scripts or verbose JSDoc JavaScript.
  • Overall less complexity.

Cons

  • A build process may still be wanted for other reasons such as bundling or React.
  • Only type annotations are supported. TypeScript features that generate code are unsupported: enums, namespaces, and constructor parameter props, will all fail to interpret. Pass the --experimental-transform-types flag to enable these features.
  • Differing import extensions. Node.js requires .ts for TypeScript imports and .js or no extension for everything else.
  • Most projects will require a massive TypeScript config (but type-stripping doesn't contribute much to that preexisting problem).

Encapsulate Interpreter with a Shebang

Executable scripts should encapsulate their invocations with a shebang:

#!/usr/bin/env -S node --experimental-strip-types --no-warnings=ExperimentalWarning

Starting with v23.6.0, type-stripping is enabled by default so --experimental-strip-types should be omitted. Mark the script executable: chmod +x foo.ts and use a .ts extension.

Testing TypeScript with the Built-in Test Runner

No Vitest or Jest required. Invoke the standard Node.js test runner with type-stripping:

$ node \
  --experimental-strip-types \
  --no-warnings=ExperimentalWarning \
  --test \
  **/*.test.ts

The Big TypeScript Config for Multiple Projects

Multi-environment projects seem to require a massive TypeScript configuration file like tools/tsconfig-base.json. This project is no better and little worse: add allowImportingTsExtensions and erasableSyntaxOnly to the base config and either rewriteRelativeImportExtensions or noEmit to each subproject.

Running NPM Scripts in Parallel

Use wait and rely on sighup to close forks.

$ npm run hello -- --goodbye&
$ sleep 10&
$ wait

This is useful for composing NPM scripts. See the dev:with-args script for an argument passing example by wrapping in a shell script.

NPM Scripts

  • run dev: run the primary development workflow.
  • install: install dependencies.
  • start: run production server.
  • test: execute all tests.
  • run test:unit: run the unit tests.

💡 Add -- to pass arguments to the script command. For example, npm run test:unit -- --test-update-snapshots to update snapshots.

Project Structure

  • src/: source inputs.
    • client/: browser code.
    • server/: server code.
    • shared/: isomorphic code.
    • test/, *.test.ts: tests and test utils.
  • tools/: development scripts and configs.

License (Public Domain)

All code in this repository is public domain and may be used without limitation.