A sane, opinionated template for ESM Node.js projects written in TypeScript without a transpilation step — TypeScript is executed directly by Node.js.
Tip
Using mise locally is the path of least friction: it manages the project-specific runtimes, tools, and tasks without requiring a container.
This template also includes an optional Arch Linux Dev Container based on mise-devcontainers. It is suggested if you do not normally use mise or want a consistent, preconfigured development environment.
Uses, among other tools/packages:
- pnpm as package manager
- Vite+ (
vp) for linting, formatting, and testing - Lefthook for Git hooks
- Commitlint with config-conventional for commit message linting
- Vitest (through Vite+) for testing
Using mise locally is recommended and provides the least-friction setup. If you do not normally use mise, the included Dev Container is an optional way to get a consistent development environment with everything preconfigured.
To use the Dev Container you need:
- Docker or a compatible container runtime
- a Dev Container-compatible editor or the Dev Container CLI
- an SSH agent exposed through
SSH_AUTH_SOCKwith at least one key loaded
The SSH agent is forwarded into the container for Git authentication and commit signing. Private keys remain on the host.
If you use the Dev Container, once inside it, install the project dependencies:
pnpm installThe project-specific runtimes and development tools are managed by mise.
If you do not use the Dev Container, install mise locally and run mise install before installing the project dependencies.
Note
After mise installs the configured tools, the post-install hook installs project packages and then sets up the Lefthook Git hooks.
Note
Git hooks keep the tooling managed by mise and the project dependencies synchronized after checkouts and merges.
Subpath imports (#/) are used instead of relative paths. They are mapped through the imports field in package.json, allowing native Node.js resolution at runtime without additional build tooling, and mirrored in tsconfig.json for editor support.
Example:
import { add } from "#/lib/math"; // ./src/lib/math.tsRuns the project in watch mode.
Runs the tests with coverage.
Options:
--ci: runs without coverage, bails on the first failure, and uses the GitHub Actions reporter--staged: runs only the tests related to staged files, with the same bail and reporter settings
mise run test -- --ciRuns Vite+ checks (vp check) over the project, or over the given file paths.
Options:
--fix: applies fixes and formatting in place- file paths: limits the check to those files
mise run check -- --fix src/main.tsCI is provided by GitHub Actions through .github/workflows/checks.yml.
It runs:
- Vite+ checks (
mise run check) - Vitest tests in CI mode (
mise run test -- --ci)