gaji 0.3.2

Type-safe GitHub Actions workflows in TypeScript
Documentation
---
layout: home

hero:
  name: gaji
  text: Type-safe GitHub Actions
  tagline: Write GitHub Actions workflows in TypeScript with full type safety
  image:
    src: /logo.png
    alt: gaji
  actions:
    - theme: brand
      text: Get Started
      link: /guide/getting-started
    - theme: alt
      text: View on GitHub
      link: https://github.com/dodok8/gaji

features:
  - icon: 🔒
    title: Full Type Safety
    details: Write workflows in TypeScript with autocomplete and type checking for every action input and output.

  - icon: ⚡
    title: Fast Development
    details: File watching with automatic type generation. Change your workflow and see results immediately.

  - icon: 🎯
    title: Zero Configuration
    details: Automatic action.yml fetching and type generation. Just use getAction() and you're ready to go.

  - icon: 🦀
    title: Single Binary
    details: Built with Rust for maximum performance. Bundles QuickJS internally - no Node.js or external JS runtime required.

  - icon: 📄
    title: Standalone TypeScript
    details: Generated workflow files are completely standalone. Run with any TS runtime (tsx, ts-node, Deno) to output workflow JSON.

  - icon: 📦
    title: Works Everywhere
    details: Use with any language or build tool. Supports existing projects without restructuring your repository.

  - icon: 🔄
    title: Easy Migration
    details: Migrate existing YAML workflows to TypeScript with a single command.
---

## What is gaji?

**gaji** stands for **G**itHub **A**ctions **J**ustified **I**mprovements.

The name also comes from the Korean word "가지" (gaji), meaning eggplant 🍆 - a versatile ingredient that makes everything better, just like this tool makes GitHub Actions workflows better!

## Why gaji?

Writing GitHub Actions workflows in YAML is error-prone and lacks type safety. gaji lets you write workflows in TypeScript, giving you:

### Before (YAML)

```yaml
name: CI
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-versoin: '20'  # Typo in key! No error until runtime ❌
          cache: 'npm'

      - run: npm ci
      - run: npm test
```

### After (TypeScript with gaji)

```ts twoslash
// @filename: workflows/example.ts
// ---cut---
import { getAction, Job, Workflow } from "../generated/index.js";

const checkout = getAction("actions/checkout@v5");
const setupNode = getAction("actions/setup-node@v4");

const build = new Job("ubuntu-latest")
  .addStep(checkout({}))
  .addStep(setupNode({
    with: {
      "node-version": "20",  // ✅ Correct key name caught at compile time
      cache: "npm",          // ✅ Full autocomplete and type checking
    },
  }))
  .addStep({ run: "npm ci" })
  .addStep({ run: "npm test" });

const workflow = new Workflow({
  name: "CI",
  on: { push: { branches: ["main"] } },
}).addJob("build", build);

workflow.build("ci");
```

## Quick Start

### Installation

```bash
# Install via npm
npm install -D gaji

# Or install via cargo
cargo install gaji
```

::: tip No JS Runtime Required
gaji bundles QuickJS internally, so you don't need Node.js or any external JavaScript runtime. Works with any language or build tool!
:::

### Setup

```bash
# Initialize
gaji init

# Add actions
gaji add actions/checkout@v5
gaji add actions/setup-node@v4

# Generate types
gaji dev

# Build workflows
gaji build
```

Generated YAML appears in `.github/workflows/` and is ready to use!

::: tip Standalone TypeScript Files
Your workflow TypeScript files are completely standalone and self-contained. You can run them directly with any TypeScript runtime to see the workflow JSON:

```bash
# Using tsx
npx tsx workflows/ci.ts

# Using ts-node
npx ts-node workflows/ci.ts

# Using Deno
deno run workflows/ci.ts
```

This makes it easy to debug, inspect, or integrate workflows into other tools!
:::

## Recommended Workflow

1. **Start watch mode**: `gaji dev --watch`
2. **Edit TypeScript workflows** in `workflows/*.ts`
3. **Build to YAML**: `gaji build`
4. **Review generated YAML** in `.github/workflows/`
5. **Commit both TypeScript and YAML**

::: warning Important
While you can create a workflow that auto-compiles TypeScript to YAML on push, **this is NOT recommended**. Always compile and review locally before committing.

If you're willing to handle the complexity of GitHub Actions triggers (e.g., filtering `paths`, managing PAT tokens, avoiding infinite loops), you can set up an auto-compilation workflow. See [`workflows/update-workflows.ts`](https://github.com/dodok8/gaji/blob/main/workflows/update-workflows.ts) for a working example.
:::

## Learn More

- [Getting Started Guide]/guide/getting-started
- [CLI Reference]/reference/cli
- [Examples]/examples/simple-ci