No description
  • TypeScript 83.3%
  • JavaScript 16.7%
Find a file
2026-05-19 19:14:08 +02:00
scripts Updated from @temir.ra/template@0.1.3 template. 2026-04-13 16:13:40 +02:00
src generalized error message in cli.ts to allow for simple clone without the need to edit the file 2026-04-12 16:01:39 +02:00
template 1. Minor updates to ensure consistency across templates. 2026-05-19 18:14:04 +02:00
tests 2. Updated files from template template and template files from ts-lib template. 2026-05-19 19:09:58 +02:00
.gitignore version 0.4.3 2026-04-13 23:20:49 +02:00
CHANGELOG.md version 0.4.6 2026-05-19 19:13:45 +02:00
LICENSE initializing the package from @temir.ra/ts-lib 2026-03-03 23:11:18 +01:00
package.json version 0.4.6 2026-05-19 19:13:45 +02:00
README.md 2. Updated files from template template and template files from ts-lib template. 2026-05-19 19:09:58 +02:00
tsconfig.json 2. Updated files from template template and template files from ts-lib template. 2026-05-19 19:09:58 +02:00

Introduction

The base template of the family. Scaffolds a Bun package: package.json, TypeScript configuration, and conventions for testing, change management, and git versioning. Use it as-is, extend it into a monorepo, or choose a more specific template from the family for common upgrade paths.

For some use cases a purpose-built template already exists and reduces the amount of manual adjustment needed. Use the table to decide whether to start here or with a more specific template.

Templates in this family:

Template Purpose
create-workspace Base Bun package; root of the template family (this template)
create-ts-lib TypeScript library with build pipeline, distributed via registry
create-hono-server Bun+Hono web server
create-hono-spa SPA scaffold, pluggable into a Hono server as a sub-app
create-skill LLM skill package
create-doc Document as a collection of Markdown sections, compiled to PDF

Table of Contents

  1. Quick Start
  2. Documentation
    1. package.json
    2. Script scripts/build-bundle.ts`
    3. tsconfig.json
    4. Workspaces
    5. Script Propagation
    6. Cross-workspace Dependencies
    7. Scaffolding Patterns
      1. Library
      2. Server
      3. Server + SPA
      4. Full-Stack with Shared Types
      5. Skill
  3. DevOps
    1. Change Management
    2. Publish

Quick Start

# placeholder:
    # <TEMPLATE_PACKAGE: @temir.ra/create-workspace
    # <TEMPLATE_NAME: @temir.ra/workspace
    # <NEW_PACKAGE: <NEW_PACKAGE>
      # is used as:
      #   - the path where the package is created
      #   - the "name" field in the generated package.json
    # <@_VERSION: <@_VERSION>

# pinned version
bun info "@temir.ra/create-workspace" version
bun create --no-install --no-git "@temir.ra/workspace<@_VERSION>" <NEW_PACKAGE>

# latest
# clear the cache to pick up the latest version
bun pm cache rm
bun create --no-install --no-git "@temir.ra/workspace" <NEW_PACKAGE>

# templates only copy files, run install and any setup scripts manually
cd <NEW_PACKAGE>
bun install

Documentation

The following sections explain the configurations and conventions baked into the generated package. Useful when adapting it to fit specific needs.

package.json

See npmjs documentation on package.json for detailed explanations of all fields.

{

  "name": "",
  "version": "0.0.0",

  "description": "",
  "author": "",
  "license": "",

  "keywords": [],

  "repository": {
    "type": "git",
    "url": ""
  },

  // controls whether the package can be published to a registry
  "private": true,

  "scripts": {

    // deletes node_modules and the lockfile, clears the Bun cache, then reinstalls
    // useful for recovering from a corrupted node_modules or lockfile
    "reinstall": "rm -rf node_modules && rm -f bun.lock && bun pm cache rm && bun install && bunx tsc --version",

    // type-checks the project without emitting output
    "typecheck": "tsc --noEmit",

    // generates buildinfo.txt (for use in lifecycle hooks and CI pipelines)
    "buildinfo": "bun run scripts/buildinfo.ts"

  },

  "devDependencies": {
    "@types/bun": "latest",
    "typescript": "^6.0.3"
  }

}

Script scripts/buildinfo.ts

Writes buildinfo.txt with the package version from package.json, appending the git short hash as semver build metadata (<version>+<hash>). If the version already contains +, the hash is appended as <version>+<existing>.<hash> instead. Falls back to the bare version when git is unavailable.

tsconfig.json

See the TypeScript documentation on tsconfig.json for detailed explanations of all options.

{

  "compilerOptions": {

    // ECMAScript version of emitted output; ESNext targets the latest JS version supported by the TypeScript compiler
    // if the package must support older runtimes or browsers, pin to a specific year (e.g. "ES2022", "ES2024")
    "target": "ESNext",

    // output module format; ESNext passes ES module syntax through unchanged
    // ES module syntax: import/export statements (as opposed to CommonJS require()/module.exports)
    "module": "ESNext",

    // type definitions for built-in APIs
    "lib": [
      "ESNext"  // standard JavaScript runtime APIs
    ],

    // module resolution strategy; bundler mode allows omitting file extensions in imports
    "moduleResolution": "bundler",

    // enables all strict type-checking options
    "strict": true,

    // enforces import type for type-only imports; emitted module syntax matches source exactly
    "verbatimModuleSyntax": true,

    // array indexing and index signature access returns T | undefined instead of T
    "noUncheckedIndexedAccess": true,

    // distinguishes absent optional properties from those explicitly set to undefined
    "exactOptionalPropertyTypes": true,

    // requires explicit override keyword when overriding base class methods
    "noImplicitOverride": true,

    // requires explicit types on all exported declarations; enables parallel .d.ts generation by external tools
    "isolatedDeclarations": true,

    // allows default imports from CommonJS modules
    "esModuleInterop": true,

    // enables project references and incremental builds via *.tsbuildinfo
    "composite": true,

    // do not type-check `.d.ts` files in `node_modules/`
    "skipLibCheck": true,

    // TS6 defaults types to [] - @types/* packages must be listed explicitly
    "types": ["bun"],

    // enforce consistent casing across import statements
    "forceConsistentCasingInFileNames": true,

    // allows importing JSON files as typed modules
    "resolveJsonModule": true

  },

  // files matched by include are type-checked and visible to the IDE (IntelliSense, go-to-definition, etc.)
  "include": [
    "scripts/**/*.ts"
  ],
  // files matched by exclude are hidden from the IDE and excluded from type-checking
  "exclude": [
    "node_modules/"
  ]

}

Workspaces

To extend the package into a monorepo, add a workspaces field to package.json and run bun install:

{
  "workspaces": [
    "packages/*"
  ]
}

The execution environment installs all workspace dependencies into a single shared node_modules/ at the root and symlinks each workspace package by its name field. Cross-workspace imports resolve by package name without path aliases or module mapping.

<NEW_PACKAGE>/
├── package.json          ← root
└── packages/
    ├── pkg-a/
    │   ├── package.json
    │   └── ...
    └── pkg-b/
        ├── package.json
        └── ...

Script Propagation

Append && bun run --filter './*' <script> to any script to propagate the call to all workspace packages:

{
  "scripts": {
    "clean:dist": "rm -rf dist/ && bun run --filter './*' clean:dist",
    "clean:tsbuildinfo": "rm -f *.tsbuildinfo && bun run --filter './*' clean:tsbuildinfo",
    "tests": "bun test && bun run --filter './*' tests",
    "typecheck": "bun run --filter './*' typecheck"
  }
}

./* targets all direct workspace packages. Replace with a more specific glob to limit propagation to a subset.

By default packages are run in sequence. Add --parallel to run them concurrently, or --sequential to make it explicit:

bun run --filter './*' --parallel typecheck
bun run --filter './*' --sequential clean

Cross-workspace Dependencies

To use one workspace package from another, declare it as a dependency using the workspace: protocol:

// packages/pkg-a/package.json
{
  "dependencies": {

    // workspace: resolves to the local package instead of fetching from a registry;
    // workspace:* tracks the exact local version;
    // workspace:^ is replaced by ^version on publish, tracking the semver range in the registry
    "@scope/pkg-b": "workspace:*"

  }
}

Run bun install after adding the entry. The execution environment creates the symlink in node_modules/ so imports resolve by package name at runtime and at the type level - no path alias or paths mapping required.

Scaffolding Patterns

Scaffold the package first, add workspaces to package.json, then scaffold workspace packages inside it. After scaffolding each workspace package, update its package.json with the correct name, version, description, author, license, and repository fields. To wire cross-workspace dependencies, add the workspace:* entry to the consuming package's package.json and run bun install from the root.

Library

<NEW_PACKAGE>/
└── packages/
    └── my-lib/        ← create-ts-lib
bun create --no-install --no-git "@temir.ra/create-workspace" <NEW_PACKAGE>
cd <NEW_PACKAGE>
bun create --no-install --no-git "@temir.ra/ts-lib" packages/my-lib
bun install
create-ts-lib

Starting point for any package distributed via a registry. See the full documentation at @temir.ra/create-ts-lib.

  • Dual tsconfig: tsconfig.json (dev, bundler resolution, includes tests/ + scripts/) and tsconfig.build.json (prod, nodenext, src/ only, emits JS + .d.ts)
  • exports conditions: entrypoint (custom, source entry for the bundle script), types, browser (bundled output), import (compiled ESM)
  • imports field: #src/*.js./src/*.ts - runtime alias for dev.ts, tests/, scripts/ only
  • Build metadata: scripts/buildinfo.ts generates buildinfo.txt (version + git hash) as a prebuild hook
  • Bundle script: scripts/build-lib-bundle.ts bundles via Bun; supports CDN specifier rewriting via cdn-rewrite-map.json
  • Asset resolution contract: assets under assets/@scope/lib-name/, accessed via import.meta.url + fetch()
  • Optional CLI entry point via bin field and build:cli-bundle script

Server

<NEW_PACKAGE>/
└── packages/
    └── server/        ← create-hono-server
bun create --no-install --no-git "@temir.ra/create-workspace" <NEW_PACKAGE>
cd <NEW_PACKAGE>
bun create --no-install --no-git "@temir.ra/hono-server" packages/server
bun install
create-hono-server

Starting point for any HTTP backend. See the full documentation at @temir.ra/create-hono-server.

  • createAppHost(options) - configures and returns a Hono<AppEnv> instance
  • Built-in middleware pipeline: Logging, requestId, RequestLogger, compress, secureHeaders
  • Built-in endpoints: /health, /buildinfo, OpenAPI spec, Scalar UI
  • endpointGroups - mounts additional Hono sub-apps; integration point for SPA packages
  • AppEnv - exported, extensible context type; extend it to carry custom variables through the context
  • startServerHost(options) - wraps Bun.serve(), graceful shutdown on SIGINT/SIGTERM

Server + SPA

<NEW_PACKAGE>/
└── packages/
    ├── server/        ← create-hono-server
    └── spa/           ← create-hono-spa
bun create --no-install --no-git "@temir.ra/create-workspace" <NEW_PACKAGE>
cd <NEW_PACKAGE>
bun create --no-install --no-git "@temir.ra/hono-server" packages/server
bun create --no-install --no-git "@temir.ra/hono-spa" packages/spa
bun install

Add the SPA as a dependency of the server, then reinstall:

// packages/server/package.json
{
  "dependencies": {
    "@scope/spa": "workspace:*"
  }
}
bun install
create-hono-spa

Starting point for a frontend SPA distributed as a Hono sub-app library. See the full documentation at @temir.ra/create-hono-spa.

  • createSpa(options) - returns a Hono sub-app serving the SPA shell
  • /app/* wildcard handles client-side routing; <base href> patched at request time from basePath and path
  • Assets resolved via import.meta.url; no file copying or static serving config needed on the consuming server
  • PWA scaffold in assets/: index.html, favicon.svg, manifest.webmanifest, screenshots
  • Distributed as a library (exports + dist/ + assets/); consumed via workspace:* in the server

Full-Stack with Shared Types

<NEW_PACKAGE>/
└── packages/
    ├── server/        ← create-hono-server
    ├── spa/           ← create-hono-spa
    └── types/         ← create-ts-lib
bun create --no-install --no-git "@temir.ra/create-workspace" <NEW_PACKAGE>
cd <NEW_PACKAGE>
bun create --no-install --no-git "@temir.ra/hono-server" packages/server
bun create --no-install --no-git "@temir.ra/hono-spa" packages/spa
bun create --no-install --no-git "@temir.ra/ts-lib" packages/types
bun install

Add the types package as a dependency of both the server and the SPA, then reinstall:

// packages/server/package.json  and  packages/spa/package.json
{
  "dependencies": {
    "@scope/types": "workspace:*"
  }
}
bun install

Skill

<NEW_PACKAGE>/
└── packages/
    └── my-skill/      ← create-skill
bun create --no-install --no-git "@temir.ra/create-workspace" <NEW_PACKAGE>
cd <NEW_PACKAGE>
bun create --no-install --no-git "@temir.ra/skill" packages/my-skill
bun install
create-skill

Starting point for any LLM skill package. See the full documentation at @temir.ra/create-skill.

  • skill/skill.json — the skill definition: frontmatter (slug, description) and body (name, purpose, activation conditions, instructions, examples, sections)
  • skill/ — typed schema, render helpers, and companion files (assets/, references/)
  • scripts/ — one build script per target platform; ships builders for Claude and OpenCode
  • dist/ — generated artifacts, one subdirectory per platform; deploy by copying dist/<platform>/<slug>/ into the target AI tool's skill directory

DevOps

bun update
bun install

bun run clean
bun run build
bun run tests

# see publish section for publish instructions

Change Management

  1. Create a new branch for the change.
  2. Make the changes and commit.
  3. Bump the version in package.json.
  4. Add an entry for the new version in CHANGELOG.md.
  5. Pull request the branch.
  6. Ensure package artifacts are current.
  7. Publish.

Publish

Publish to the public npm registry.

# authenticate
npm login
# publish
bun publish --registry https://registry.npmjs.org/ --access public