setup-base

SKILL.md

Setup

Bootstrap a new TypeScript project with the following base tooling:

  • Biome (via ultracite presets)
  • t3-env for type-safe environment variables
  • Knip for unused code detection
  • TypeScript with tsgo
  • Vitest for testing

Why This Stack

Each tool solves a specific problem in the development workflow:

  • Biome (via ultracite) — Single tool for formatting and linting, replacing ESLint + Prettier. Significantly faster due to Rust implementation.
  • t3-env — Validates environment variables at startup so missing or malformed values fail immediately instead of causing silent runtime bugs.
  • Knip — Detects unused exports, dependencies, and files. Keeps the codebase lean as it evolves.
  • tsgo (@typescript/native-preview) — Native Go port of TypeScript's type checker, substantially faster than tsc.

Steps

Follow the bellow steps in this exact order:

1. Create package.json

{
  "name": "<project-name>",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "lint": "biome check",
    "setup": "bun install",
    "types": "tsgo --build",
    "test": "vitest run",
    "unused": "knip",
    "update": "taze --interactive",
    "validate": "bun run lint && bun run types && bun run unused && bun run test"
  },
  "dependencies": {},
  "devDependencies": {}
}

2. Install dependencies

bun add @t3-oss/env-core zod
bun add -d @biomejs/biome @types/node @typescript/native-preview knip taze ultracite vitest

3. Create tsconfig.json

{
  "compilerOptions": {
    "allowImportingTsExtensions": true,
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "incremental": true,
    "isolatedModules": true,
    "lib": ["esnext"],
    "module": "esnext",
    "moduleDetection": "force",
    "moduleResolution": "bundler",
    "noEmit": true,
    "noUncheckedIndexedAccess": true,
    "noUncheckedSideEffectImports": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "esnext",
    "verbatimModuleSyntax": false
  },
  "exclude": ["node_modules"],
  "include": ["**/*.ts"]
}

4. Create biome.jsonc

{
  "$schema": "node_modules/@biomejs/biome/configuration_schema.json",
  "extends": ["ultracite/core"],
  "formatter": {
    "lineWidth": 100
  }
}

5. Create .gitignore

# base
*.local*
*.tsbuildinfo
.DS_Store
node_modules

6. Create src/lib/env.ts

import { createEnv } from "@t3-oss/env-core";

export const env = createEnv({
  emptyStringAsUndefined: true,
  runtimeEnv: process.env,
  server: {},
});

7. Create .github/workflows/ci.yml

A CI pipeline that runs the validate script on every push, catching lint errors, type issues, and unused code before it reaches main.

name: CI

on:
  push:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Bun
        uses: oven-sh/setup-bun@v1
      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
          restore-keys: |
            ${{ runner.os }}-bun-
      - name: Install dependencies
        run: bun install
      - name: Run Validate Script
        run: bun run validate

8. Create vitest.config.ts

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    include: ["src/**/*.test.ts"],
  },
});

9. Create src/lib/env.test.ts

import { describe, expect, test } from "vitest";
import { env } from "./env";

describe("env", () => {
  test("initializes without error", () => {
    expect(env).toBeDefined();
  });
});
Weekly Installs
1
GitHub Stars
4
First Seen
12 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1