CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-projen

CDK for software projects - synthesizes configuration files from well-typed JavaScript/TypeScript definitions.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

nodejs-projects.mddocs/

Node.js Projects

Node.js projects with package management, testing frameworks, and JavaScript tooling. Provides comprehensive setup for Node.js applications and libraries with modern development tools.

Capabilities

NodeProject Class

Base Node.js project with npm/yarn package management and integrated tooling ecosystem.

/**
 * Node.js project with npm/yarn package management and tooling
 * Base class for JavaScript and TypeScript projects
 */
class NodeProject extends GitHubProject {
  constructor(options: NodeProjectOptions);
  
  /** Package.json management */
  readonly package: NodePackage;
  /** Jest testing framework (if enabled) */
  readonly jest?: Jest;
  /** Prettier code formatting (if enabled) */
  readonly prettier?: Prettier;
  /** Biome linting and formatting (if enabled) */
  readonly biome?: Biome;
  /** Code bundling system (always available) */
  readonly bundler: Bundler;
  /** Dependency upgrade automation */
  readonly upgradeWorkflow?: UpgradeDependencies;
  /** Package manager type (npm, yarn, pnpm, bun) */
  readonly packageManager: NodePackageManager;
  /** Node.js version requirement */
  readonly nodeVersion?: string;
  /** Package installation command */
  readonly installCommand: string;
  /** Package run command prefix */
  readonly runScriptCommand: string;
  /** The .npmignore file */
  readonly npmignore?: IgnoreFile;
  /** The .npmrc file */
  readonly npmrc: NpmConfig;
  /** Component that sets up mergify for merging approved pull requests */
  readonly autoMerge?: AutoMerge;
  /** The PR build GitHub workflow */
  readonly buildWorkflow?: BuildWorkflow;
  /** Package publisher (deprecated - use release.publisher) */
  readonly publisher?: Publisher;
  /** Release management */
  readonly release?: Release;
  /** Minimum node version required by this package */
  readonly minNodeVersion?: string;
  /** Maximum node version supported by this package */
  readonly maxNodeVersion?: string;
  /** Build output directory for npm tarballs */
  readonly artifactsDirectory: string;
  /** Location of npm tarball after build */
  readonly artifactsJavascriptDirectory: string;
  /** Deprecated - use package.allowLibraryDependencies */
  readonly allowLibraryDependencies: boolean;
  /** Deprecated - use package.entrypoint */
  readonly entrypoint: string;
  /** Deprecated - use package.manifest */
  readonly manifest: any;
  
  /** Add binary executables to package.json */
  addBins(bins: Record<string, string>): void;
  /** Set npm script command */
  setScript(name: string, command: string): void;
  /** Add multiple npm scripts */
  addScripts(scripts: Record<string, string>): void;
  /** Remove npm script */
  removeScript(name: string): void;
  /** Check if script exists (deprecated) */
  hasScript(name: string): boolean;
  /** Add compile command (deprecated) */
  addCompileCommand(...commands: string[]): void;
  /** Add test command (deprecated) */
  addTestCommand(...commands: string[]): void;
  /** Set package.json fields directly */
  addFields(fields: Record<string, any>): void;
  /** Add keywords to package.json */
  addKeywords(...keywords: string[]): void;
  /** Add dependencies */
  addDeps(...deps: string[]): void;
  /** Add development dependencies */
  addDevDeps(...deps: string[]): void;
  /** Add peer dependencies */
  addPeerDeps(...deps: string[]): void;
  /** Add bundled dependencies */
  addBundledDeps(...deps: string[]): void;
  /** Add patterns to .npmignore */
  addPackageIgnore(pattern: string): void;
  /** Render workflow setup steps */
  renderWorkflowSetup(options?: RenderWorkflowSetupOptions): JobStep[];
  /** Get shell command to run a task */
  runTaskCommand(task: Task): string;
  /** The job ID of the build workflow */
  readonly buildWorkflowJobId?: string;
}

interface NodeProjectOptions extends GitHubProjectOptions, NodePackageOptions, ReleaseProjectOptions {
  /** License copyright owner */
  copyrightOwner?: string;
  /** Copyright years for LICENSE file */
  copyrightPeriod?: string;
  /** Projen version to install */
  projenVersion?: string;
  /** Install projen as devDependency */
  projenDevDependency?: boolean;
  
  /** Define GitHub workflow for building PRs */
  buildWorkflow?: boolean;
  /** Options for PR build workflow */
  buildWorkflowOptions?: BuildWorkflowOptions;
  /** Deprecated - use buildWorkflowOptions.mutableBuild */
  mutableBuild?: boolean;
  
  /** Enable codecov integration */
  codeCov?: boolean;
  /** Codecov token secret name */
  codeCovTokenSecret?: string;
  
  /** Deprecated - renamed to release */
  releaseWorkflow?: boolean;
  /** Add release management */
  release?: boolean;
  /** Main release branch name */
  defaultReleaseBranch: string;
  
  /** Workflow bootstrap steps */
  workflowBootstrapSteps?: JobStep[];
  /** Git identity for workflows */
  workflowGitIdentity?: GitIdentity;
  /** Automatically release to npm */
  releaseToNpm?: boolean;
  /** Node version for GitHub Actions workflows */
  workflowNodeVersion?: string;
  /** Enable package cache in workflows */
  workflowPackageCache?: boolean;
  
  /** Use dependabot for dependency upgrades */
  dependabot?: boolean;
  /** Dependabot options */
  dependabotOptions?: DependabotOptions;
  /** Use tasks/workflows for dependency upgrades */
  depsUpgrade?: boolean;
  /** Dependency upgrade options */
  depsUpgradeOptions?: UpgradeDependenciesOptions;
  /** Auto-approve deps upgrade PRs */
  autoApproveUpgrades?: boolean;
  
  /** Enable .npmignore file */
  npmignoreEnabled?: boolean;
  /** Configuration for .npmignore */
  npmIgnoreOptions?: IgnoreFileOptions;
  /** Deprecated - use project.addPackageIgnore */
  npmignore?: string[];
  
  /** Include GitHub pull request template */
  pullRequestTemplate?: boolean;
  /** Contents of pull request template */
  pullRequestTemplateContents?: string[];
  
  /** Setup Prettier */
  prettier?: boolean;
  /** Prettier options */
  prettierOptions?: PrettierOptions;
  
  /** Additional .gitignore entries */
  gitignore?: string[];
  
  /** Setup Jest unit tests */
  jest?: boolean;
  /** Jest options */
  jestOptions?: JestOptions;
  
  /** Generate .projenrc.js */
  projenrcJs?: boolean;
  /** Options for .projenrc.js */
  projenrcJsOptions?: ProjenrcOptions;
  
  /** Bundler options */
  bundlerOptions?: BundlerOptions;
  
  /** Build artifacts directory */
  artifactsDirectory?: string;
  /** Produce npm tarball */
  package?: boolean;
  
  /** Deprecated - use buildWorkflowOptions.workflowTriggers */
  buildWorkflowTriggers?: Triggers;
  
  /** License checker configuration */
  checkLicenses?: LicenseCheckerOptions;
  
  /** Setup Biome */
  biome?: boolean;
  /** Biome options */
  biomeOptions?: BiomeOptions;
}

enum NodePackageManager {
  NPM = "npm",
  YARN = "yarn", 
  YARN_CLASSIC = "yarn_classic",
  YARN2 = "yarn2",
  YARN_BERRY = "yarn_berry",
  PNPM = "pnpm",
  BUN = "bun"
}

enum AutoRelease {
  /** Automatically bump & release for every commit to main */
  EVERY_COMMIT = "every-commit",
  /** Automatically bump & release on a daily basis */
  DAILY = "daily"
}

interface BuildWorkflowOptions extends BuildWorkflowCommonOptions {
  /** Update files during builds to PR branches */
  mutableBuild?: boolean;
}

interface RenderWorkflowSetupOptions {
  /** Configure install step in workflow setup */
  installStepConfiguration?: JobStepConfiguration;
  /** Should package lockfile be updated */
  mutable?: boolean;
}

Basic Node.js Project Example:

import { NodeProject, NodePackageManager } from "projen";

const project = new NodeProject({
  name: "my-node-app",
  defaultReleaseBranch: "main",
  
  // Package information
  description: "My awesome Node.js application",
  keywords: ["nodejs", "api", "express"],
  license: "MIT",
  author: "Jane Developer",
  authorEmail: "jane@example.com",
  
  // Package manager
  packageManager: NodePackageManager.YARN,
  nodeVersion: ">=16.0.0",
  
  // Dependencies
  deps: [
    "express@^4.18.0",
    "cors@^2.8.5",
    "helmet@^6.0.0",
  ],
  devDeps: [
    "@types/express",
    "@types/cors",
    "nodemon",
  ],
  
  // Tooling
  jest: true,
  prettier: true,
});

// Add custom scripts
project.package.addScript("start", "node dist/index.js");
project.package.addScript("dev", "nodemon src/index.js");
project.package.addScript("build", "echo 'No build step for plain JS'");

Jest Testing Framework

Comprehensive testing setup with Jest including coverage and reporting.

/**
 * Jest testing framework configuration
 * Provides unit testing, integration testing, and coverage reporting
 */
class Jest extends Component {
  constructor(project: NodeProject, options?: JestOptions);
  
  /** Jest configuration object */
  readonly config: any;
  /** Test task */
  readonly testTask: Task;
  /** Watch test task */
  readonly watchTask: Task;
  /** Coverage task */
  readonly coverageTask: Task;
  /** Jest configuration file */
  readonly file: JsonFile;
  
  /** Add Jest configuration */
  addConfig(key: string, value: any): void;
  /** Add test pattern */
  addTestMatch(pattern: string): void;
  /** Add setup file */
  addSetupFile(file: string): void;
  /** Add setup file after environment */
  addSetupFilesAfterEnv(file: string): void;
  /** Add module name mapping */
  addModuleNameMapping(pattern: string, replacement: string): void;
  /** Add ignore pattern */
  addIgnorePattern(pattern: string): void;
  /** Add watch path ignore pattern */
  addWatchIgnorePattern(pattern: string): void;
  /** Add reporter */
  addReporter(reporter: JestReporter | string): void;
  /** Add transform */
  addTransform(pattern: string, transformer: string | Transform): void;
  /** Add test environment option */
  addTestEnvironmentOptions(key: string, value: any): void;
  /** Discover test match patterns for directories */
  static discoverTestMatchPatternsForDirs(dirs: string[], options?: JestDiscoverTestMatchPatternsForDirsOptions): string[];
}

interface JestOptions {
  /** Jest version */
  jestVersion?: string;
  /** Jest configuration object */
  jestConfig?: JestConfigOptions;
  /** Preserve default Jest reporter when additional reporters are added */
  preserveDefaultReporters?: boolean;
  /** Ignore patterns for Jest */
  ignorePatterns?: string[];
  /** Update snapshot behavior */
  updateSnapshot?: UpdateSnapshot;
  /** CI environment settings */
  ci?: boolean;
  /** Coverage collection */
  coverage?: boolean;
  /** Maximum worker threads */
  maxWorkers?: string;
  /** Extra CLI options */
  extraCliOptions?: string[];
}

interface JestConfigOptions {
  /** Automatically clear mock calls and instances */
  clearMocks?: boolean;
  /** Coverage collection enabled */
  collectCoverage?: boolean;
  /** Paths from which to collect coverage */
  collectCoverageFrom?: string[];
  /** Coverage directory */
  coverageDirectory?: string;
  /** Coverage path ignore patterns */
  coveragePathIgnorePatterns?: string[];
  /** Coverage reporters */
  coverageReporters?: string[];
  /** Coverage threshold */
  coverageThreshold?: CoverageThreshold;
  /** Display name for the test */
  displayName?: string | { name: string; color: string };
  /** Error on deprecated features */
  errorOnDeprecated?: boolean;
  /** Force coverage collection from ignored files */
  forceCoverageMatch?: string[];
  /** Global setup module */
  globalSetup?: string;
  /** Global teardown module */
  globalTeardown?: string;
  /** Global variables */
  globals?: Record<string, any>;
  /** Haste configuration */
  haste?: HasteConfig;
  /** Maximum number of concurrent workers */
  maxWorkers?: number | string;
  /** Module directories */
  moduleDirectories?: string[];
  /** Module file extensions */
  moduleFileExtensions?: string[];
  /** Module name mapper */
  moduleNameMapper?: Record<string, string>;
  /** Module paths */
  modulePaths?: string[];
  /** Notify of test results */
  notify?: boolean;
  /** Preset configuration */
  preset?: string;
  /** Prettier path */
  prettierPath?: string;
  /** Projects configuration */
  projects?: string[];
  /** Reporters configuration */
  reporters?: (string | JestReporter)[];
  /** Reset mocks between tests */
  resetMocks?: boolean;
  /** Reset modules between tests */
  resetModules?: boolean;
  /** Restore mocks between tests */
  restoreMocks?: boolean;
  /** Root directory */
  rootDir?: string;
  /** Additional root directories */
  roots?: string[];
  /** Setup files */
  setupFiles?: string[];
  /** Setup files after environment */
  setupFilesAfterEnv?: string[];
  /** Snapshot serializers */
  snapshotSerializers?: string[];
  /** Test environment */
  testEnvironment?: string;
  /** Test environment options */
  testEnvironmentOptions?: Record<string, any>;
  /** Test match patterns */
  testMatch?: string[];
  /** Test path ignore patterns */
  testPathIgnorePatterns?: string[];
  /** Test results processor */
  testResultsProcessor?: string;
  /** Test runner */
  testRunner?: string;
  /** Test timeout */
  testTimeout?: number;
  /** Transform configuration */
  transform?: Record<string, string | Transform>;
  /** Transform ignore patterns */
  transformIgnorePatterns?: string[];
  /** Unmocked module path patterns */
  unmockedModulePathPatterns?: string[];
  /** Verbose output */
  verbose?: boolean;
  /** Watch path ignore patterns */
  watchPathIgnorePatterns?: string[];
}

class Transform {
  constructor(transformer: string, options?: Record<string, any>);
  
  /** Transform file path */
  readonly file: string;
  /** Transform options */
  readonly options?: Record<string, any>;
}

class WatchPlugin {
  constructor(plugin: string, options?: Record<string, any>);
  
  /** Watch plugin file path */
  readonly file: string;
  /** Watch plugin options */
  readonly options?: Record<string, any>;
}

interface JestDiscoverTestMatchPatternsForDirsOptions {
  /** File extensions to include */
  fileExtensions?: string[];
}

enum UpdateSnapshot {
  NEVER = "never",
  NEW = "new",
  ALL = "all"
}

interface HasteConfig {
  /** Enable Haste module system */
  enableSymlinks?: boolean;
  /** Force node filesystem API */
  forceNodeFilesystemAPI?: boolean;
  /** Haste implementation module path */
  hasteImplModulePath?: string;
  /** Platforms supported by Haste */
  platforms?: string[];
  /** Throw on missing module */
  throwOnModuleCollision?: boolean;
}

class JestReporter {
  constructor(reporter: string, options?: Record<string, any>);
  
  /** Reporter file path */
  readonly file: string;
  /** Reporter options */
  readonly options?: Record<string, any>;
}

interface CoverageThreshold {
  global?: {
    branches?: number;
    functions?: number;
    lines?: number;
    statements?: number;
  };
}

Jest Configuration Example:

import { NodeProject } from "projen";

const project = new NodeProject({
  name: "jest-example",
  jest: true,
  jestOptions: {
    jestConfig: {
      testMatch: [
        "<rootDir>/src/**/__tests__/**/*.ts",
        "<rootDir>/src/**/*.test.ts",
      ],
      collectCoverage: true,
      coverageDirectory: "coverage",
      coverageReporters: ["text", "lcov", "html"],
      coverageThreshold: {
        global: {
          branches: 80,
          functions: 80,
          lines: 80,
          statements: 80,
        },
      },
      testEnvironment: "node",
    },
  },
});

// Customize Jest configuration
if (project.jest) {
  project.jest.addSetupFilesAfterEnv("<rootDir>/test/setup.js");
  project.jest.addModuleNameMapping("^@/(.*)$", "<rootDir>/src/$1");
}

Prettier Formatting

Prettier code formatting with customizable style rules.

/**
 * Prettier code formatting configuration
 * Ensures consistent code style across the project
 */
class Prettier extends Component {
  static of(project: Project): Prettier | undefined;
  
  constructor(project: NodeProject, options?: PrettierOptions);
  
  /** Prettier configuration file */
  readonly file: JsonFile;
  /** Prettier ignore file */
  readonly ignoreFile: IgnoreFile;
  /** Prettier configuration object */
  readonly config: PrettierSettings;
  /** Format task */
  readonly formatTask: Task;
  
  /** Add Prettier configuration */
  addConfig(key: string, value: any): void;
  /** Add ignore pattern */
  addIgnorePattern(pattern: string): void;
  /** Add prettier override */
  addOverride(override: PrettierOverride): void;
}

interface PrettierOptions {
  /** Prettier settings */
  settings?: PrettierSettings;
  /** Ignore patterns */
  ignorePatterns?: string[];
  /** Prettier overrides */
  overrides?: PrettierOverride[];
  /** Write prettier configuration as YAML */
  yaml?: boolean;
}

interface PrettierSettings {
  /** Print width */
  printWidth?: number;
  /** Tab width */
  tabWidth?: number;
  /** Use tabs instead of spaces */
  useTabs?: boolean;
  /** Semicolons */
  semi?: boolean;
  /** Single quotes */
  singleQuote?: boolean;
  /** Quote properties */
  quoteProps?: QuoteProps;
  /** Trailing commas */
  trailingComma?: TrailingComma;
  /** Bracket spacing */
  bracketSpacing?: boolean;
  /** Arrow function parentheses */
  arrowParens?: ArrowParens;
  /** Bracket same line */
  bracketSameLine?: boolean;
  /** Embedded language formatting */
  embeddedLanguageFormatting?: EmbeddedLanguageFormatting;
  /** HTML whitespace sensitivity */
  htmlWhitespaceSensitivity?: HTMLWhitespaceSensitivity;
  /** Insert pragma */
  insertPragma?: boolean;
  /** JSX single quote */
  jsxSingleQuote?: boolean;
  /** Parser to use */
  parser?: string;
  /** Prose wrap */
  proseWrap?: ProseWrap;
  /** Range end */
  rangeEnd?: number;
  /** Range start */
  rangeStart?: number;
  /** Require pragma */
  requirePragma?: boolean;
  /** Vue indent script and style */
  vueIndentScriptAndStyle?: boolean;
  /** Line ending */
  endOfLine?: EndOfLine;
}

interface PrettierOverride {
  /** Files to apply override to */
  files: string[];
  /** Excluded files */
  excludeFiles?: string[];
  /** Override options */
  options?: PrettierSettings;
}

enum ArrowParens {
  ALWAYS = "always",
  AVOID = "avoid"
}

enum EmbeddedLanguageFormatting {
  AUTO = "auto",
  OFF = "off"
}

enum EndOfLine {
  AUTO = "auto",
  LF = "lf",
  CRLF = "crlf",
  CR = "cr"
}

enum HTMLWhitespaceSensitivity {
  CSS = "css",
  STRICT = "strict",
  IGNORE = "ignore"
}

enum ProseWrap {
  ALWAYS = "always",
  NEVER = "never",
  PRESERVE = "preserve"
}

enum QuoteProps {
  AS_NEEDED = "as-needed",
  CONSISTENT = "consistent",
  PRESERVE = "preserve"
}

enum TrailingComma {
  NONE = "none",
  ES5 = "es5",
  ALL = "all"
}

Biome Integration

Biome is an alternative to ESLint and Prettier that provides fast linting and formatting.

/**
 * Biome linting and formatting configuration
 * Fast alternative to ESLint + Prettier
 */
class Biome extends Component {
  static of(project: Project): Biome | undefined;
  
  constructor(project: NodeProject, options?: BiomeOptions);
  
  /** Biome configuration file */
  readonly file: JsonFile;
  /** Biome configuration object */
  readonly config: BiomeConfiguration;
  /** Check task for linting */
  readonly checkTask: Task;
  /** Format task for formatting */
  readonly formatTask: Task;
  
  /** Add configuration to Biome */
  addConfig(config: Partial<BiomeConfiguration>): void;
  /** Add ignore pattern */
  addIgnorePattern(pattern: string): void;
}

interface BiomeOptions {
  /** Biome configuration */
  config?: Partial<BiomeConfiguration>;
  /** Biome version */
  version?: string;
}

interface BiomeConfiguration {
  /** Schema reference */
  $schema?: string;
  /** Organize imports settings */
  organizeImports?: { enabled?: boolean };
  /** Linter configuration */
  linter?: LinterConfiguration;
  /** Formatter configuration */
  formatter?: FormatterConfiguration;
  /** JavaScript configuration */
  javascript?: JsConfiguration;
  /** Files configuration */
  files?: FilesConfiguration;
  /** JSON configuration */
  json?: JsonConfiguration;
  /** CSS configuration */
  css?: CssConfiguration;
  /** VCS configuration */
  vcs?: VcsConfiguration;
}

Code Bundling

Code bundling with esbuild for Node.js projects.

/**
 * Code bundling system for Node.js projects
 * Supports esbuild for fast bundling
 */
class Bundler extends Component {
  constructor(project: NodeProject, options?: BundlerOptions);
  
  /** Bundle task */
  readonly bundleTask: Task;
  /** Watch bundle task */
  readonly watchTask?: Task;
  /** Pre-bundle task */
  readonly preBundleTask: Task;
  /** Post-bundle task */
  readonly postBundleTask: Task;
  /** Available bundles */
  readonly bundles: Bundle[];
  
  /** Add bundle configuration */
  addBundle(bundleId: string, options: AddBundleOptions): Bundle;
  /** Execute bundle with options */
  executeBundle(bundleId: string, options: BundlingOptions): void;
}

interface BundlerOptions {
  /** Add bundle for project itself */
  addToPreBundleTask?: boolean;
}

interface Bundle {
  /** Bundle identifier */
  readonly bundleid: string;
  /** Entry point file */
  readonly entrypoint: string;
  /** Output directory */
  readonly outdir: string;
  /** External modules */
  readonly externals: string[];
  /** Runtime dependencies to bundle */
  readonly runtimeDependencies?: string[];
}

interface BundlingOptions {
  /** Entry point file */
  entrypoint: string;
  /** Output directory */
  outdir: string;
  /** External modules not to bundle */
  externals?: string[];
  /** Runtime dependencies to include */
  runtimeDependencies?: string[];
  /** Bundle executable files */
  executable?: boolean;
  /** Watch mode */
  watch?: boolean;
  /** Preserve symlinks */
  preserveSymlinks?: boolean;
  /** TSConfig file to use */
  tsconfig?: string;
  /** Loader configuration */
  loaders?: Record<string, string>;
  /** Log level */
  logLevel?: BundleLogLevel;
  /** Keep names for functions and classes */
  keepNames?: boolean;
  /** Source map mode */
  sourcemap?: SourceMapMode;
  /** Source root */
  sourcesContent?: boolean;
  /** Banner text */
  banner?: string;
  /** Footer text */
  footer?: string;
  /** Character set */
  charset?: Charset;
  /** Minify output */
  minify?: boolean;
  /** Target environment */
  target?: string;
  /** Platform target */
  platform?: string;
  /** Main fields for resolution */
  mainFields?: string[];
  /** Conditions for resolution */
  conditions?: string[];
  /** Define constants */
  define?: Record<string, string>;
  /** Tree shaking */
  treeShaking?: boolean;
  /** Code splitting */
  splitting?: boolean;
  /** Output format */
  format?: string;
  /** Asset names */
  assetNames?: string;
  /** Chunk names */
  chunkNames?: string;
  /** Entry names */
  entryNames?: string;
  /** Inject code */
  inject?: string[];
  /** Esbuild version */
  esbuildVersion?: string;
  /** Docker image for bundling */
  dockerImage?: string;
}

interface AddBundleOptions extends BundlingOptions {
  /** When to run the bundle task */
  runBundleTask?: RunBundleTask;
}

enum RunBundleTask {
  /** Run during pre-bundle phase */
  PRE_BUNDLE = "pre-bundle",
  /** Run during post-bundle phase */
  POST_BUNDLE = "post-bundle",
  /** Run manually */
  MANUAL = "manual"
}

enum SourceMapMode {
  DEFAULT = "default",
  EXTERNAL = "external",
  INLINE = "inline",
  BOTH = "both"
}

enum Charset {
  ASCII = "ascii",
  UTF8 = "utf8"
}

enum BundleLogLevel {
  SILENT = "silent",
  ERROR = "error",
  WARNING = "warning",
  INFO = "info",
  DEBUG = "debug",
  VERBOSE = "verbose"
}

Complete Node.js Project Example:

import { NodeProject, NodePackageManager } from "projen";

const project = new NodeProject({
  name: "complete-node-project",
  defaultReleaseBranch: "main",
  
  // Project metadata
  description: "A complete Node.js project with all features",
  keywords: ["nodejs", "typescript", "api"],
  license: "Apache-2.0",
  author: "Development Team",
  authorEmail: "dev@company.com",
  repository: "https://github.com/company/complete-node-project.git",
  
  // Package manager and Node version
  packageManager: NodePackageManager.YARN,
  nodeVersion: ">=18.0.0",
  
  // Dependencies
  deps: [
    "express@^4.18.0",
    "cors@^2.8.5",
    "helmet@^6.0.0",
    "dotenv@^16.0.0",
  ],
  devDeps: [
    "@types/express",
    "@types/cors",
    "nodemon",
    "supertest",
    "@types/supertest",
  ],
  
  // Testing with Jest
  jest: true,
  jestOptions: {
    jestConfig: {
      collectCoverage: true,
      coverageDirectory: "coverage",
      testEnvironment: "node",
      setupFilesAfterEnv: ["<rootDir>/test/setup.js"],
    },
  },
  
  // Formatting with Prettier
  prettier: true,
  prettierOptions: {
    settings: {
      singleQuote: true,
      trailingComma: TrailingComma.ES5,
      tabWidth: 2,
    },
  },
  
  // Bundling
  bundlerOptions: {
    addToPreBundleTask: true,
  },
  
  // Dependency upgrades
  depsUpgrade: true,
});

// Add custom bundle
project.bundler.addBundle("api", {
  entrypoint: "src/index.js",
  outdir: "dist",
  format: "cjs",
  minify: true,
  platform: "node",
});

// Custom tasks
project.addTask("start:dev", {
  description: "Start development server",
  exec: "nodemon src/index.js",
});

project.addTask("start:prod", {
  description: "Start production server", 
  exec: "node dist/index.js",
});

// Custom package.json fields
project.package.addField("engines", {
  node: ">=18.0.0",
  yarn: ">=1.22.0",
});

project.package.addScript("docker:build", "docker build -t my-app .");
project.package.addScript("docker:run", "docker run -p 3000:3000 my-app");

Types

Node.js-Specific Types

/** License checker for dependency licenses */
class LicenseChecker extends Component {
  constructor(project: NodeProject, options: LicenseCheckerOptions);
  
  /** License check task */
  readonly task: Task;
}

interface LicenseCheckerOptions {
  /** Allowed SPDX license identifiers */
  allow?: string[];
  /** Prohibited SPDX license identifiers */
  deny?: string[];
  /** Check production dependencies only */
  production?: boolean;
  /** Path to output file */
  outputFile?: string;
}

/** Upgrade dependencies automation */
class UpgradeDependencies extends Component {
  constructor(project: NodeProject, options?: UpgradeDependenciesOptions);
  
  /** Upgrade workflow */
  readonly workflow?: GitHubWorkflow;
  /** Upgrade task */
  readonly upgradeTask: Task;
  /** List of container images that will be upgraded */
  readonly containerImages: string[];
  
  /** Add package to exclude from upgrades */
  addExclude(...packageNames: string[]): void;
  /** Add package to include in upgrades */
  addInclude(...packageNames: string[]): void;
}

interface UpgradeDependenciesOptions {
  /** Include package names to upgrade */
  include?: string[];
  /** Exclude package names from upgrade */
  exclude?: string[];
  /** Workflow options */
  workflowOptions?: UpgradeDependenciesWorkflowOptions;
  /** Upgrade schedule */
  scheduleOptions?: UpgradeDependenciesScheduleOptions;
  /** Task step options */
  taskStepOptions?: TaskStepOptions;
  /** Target branch for pull requests */
  target?: string;
  /** Create a GitHub issue when upgrade fails */
  createGitHubIssue?: boolean;
  /** Labels for issues created on upgrade failure */
  gitHubIssueLabels?: string[];
  /** Title for pull requests */
  pullRequestTitle?: string;
  /** Semantic commit type for commits */
  semanticCommit?: string;
  /** Exclude packages matching these patterns */
  ignorePatterns?: string[];
  /** Include prerelease versions */
  includePrereleases?: boolean;
}

/** NPM configuration file (.npmrc) */
class NpmConfig extends Component {
  constructor(project: NodeProject, options?: NpmConfigOptions);
  
  /** Add configuration entry */
  addConfig(name: string, value: string): void;
  /** Add registry configuration */
  addRegistry(url: string, scope?: string): void;
}

interface NpmConfigOptions {
  /** Omit empty values */
  omitEmpty?: boolean;
}

interface PackageJson {
  name: string;
  version: string;
  description?: string;
  main?: string;
  scripts?: Record<string, string>;
  dependencies?: Record<string, string>;
  devDependencies?: Record<string, string>;
  peerDependencies?: Record<string, string>;
  optionalDependencies?: Record<string, string>;
  bundledDependencies?: string[];
  keywords?: string[];
  author?: string | AuthorInfo;
  license?: string;
  repository?: string | RepositoryInfo;
  bugs?: string | BugsInfo;
  homepage?: string;
  engines?: Record<string, string>;
}

interface AuthorInfo {
  name: string;
  email?: string;
  url?: string;
}

interface RepositoryInfo {
  type: string;
  url: string;
  directory?: string;
}

interface BugsInfo {
  url?: string;
  email?: string;
}

Install with Tessl CLI

npx tessl i tessl/npm-projen

docs

awscdk-projects.md

core-project.md

dependency-management.md

file-management.md

github-integration.md

index.md

java-projects.md

nodejs-projects.md

python-projects.md

task-management.md

typescript-projects.md

web-projects.md

tile.json