Skip to content

Portable Recipe Syntax Reference ​

Portable recipes are JavaScript files executed in Fabrik's embedded QuickJS runtime. They can be run locally or fetched from Git repositories.

Local Recipes ​

Run any .js file directly with Fabrik's embedded QuickJS runtime:

bash
fabrik run <path/to/recipe.js>

Examples ​

bash
# Run a recipe in the current directory
fabrik run build.js

# Run a recipe in a subdirectory
fabrik run scripts/deploy.js

# Run with verbose output
fabrik run --verbose build.js

# Absolute path
fabrik run /path/to/my/recipe.js

How It Works ​

When you run a .js file with fabrik run:

  1. Fabrik detects the .js extension
  2. Loads the file into the embedded QuickJS runtime
  3. Provides access to Fabrik APIs (fabrik:cache, fabrik:kv, fabrik:fs)
  4. Provides Node.js-compatible APIs (fs, child_process, path)
  5. Executes the recipe

Example Recipe ​

javascript
// build.js
import { spawn } from 'child_process';
import { glob } from 'fabrik:fs';

console.log("Building project...");

const files = await glob("src/**/*.ts");
console.log(`Found ${files.length} TypeScript files`);

const result = await spawn("npm", ["run", "build"]);
if (result.exitCode !== 0) {
    throw new Error("Build failed!");
}

console.log("Build complete!");

Remote Recipes ​

Fetch and run recipes directly from Git repositories using the @ prefix syntax:

bash
fabrik run @[host/]org/repo/path/script.js[@ref]

Components ​

Required Components ​

@ Prefix All remote recipes must start with @ to differentiate them from local file paths.

Organization/User (org) The GitHub/GitLab organization or username.

Repository (repo) The repository name.

Path (path/script.js) The path to the recipe file within the repository. Can include subdirectories.

Optional Components ​

Host (host) The Git server hostname. Defaults to github.com if not specified.

Examples:

  • github.com (default)
  • gitlab.com
  • git.company.com (self-hosted)

Git Reference (@ref) A Git branch, tag, or commit SHA. Defaults to main if not specified.

Examples:

  • @main (branch)
  • @v1.0.0 (tag)
  • @abc123def (commit SHA)

Remote Syntax Examples ​

GitHub (Default Host) ​

bash
# Simple (uses main branch)
fabrik run @tuist/recipes/build.js

# With version tag
fabrik run @tuist/recipes/build.js@v1.0.0

# Nested path
fabrik run @tuist/recipes/scripts/deploy/production.js

# With branch
fabrik run @tuist/recipes/build.js@develop

GitLab ​

bash
# Simple
fabrik run @gitlab.com/myorg/myrepo/build.js

# With version
fabrik run @gitlab.com/myorg/myrepo/build.js@v2.0.0

# Nested path
fabrik run @gitlab.com/myorg/myrepo/ci/deploy.js@release

Self-Hosted Git ​

bash
# Company Git server
fabrik run @git.company.com/team/project/build.js

# With specific commit
fabrik run @git.company.com/team/project/build.js@abc123def

# Nested path
fabrik run @git.company.com/team/project/scripts/test.js@main

Cache Directory Structure ​

Remote recipes are cached following XDG Base Directory conventions:

~/.cache/fabrik/recipes/
├── github.com/
│   └── tuist/
│       └── recipes/
│           ├── main/              # Default branch
│           │   ├── build.js
│           │   └── deploy.js
│           ├── v1.0.0/            # Tagged version
│           │   └── build.js
│           └── develop/           # Branch
│               └── experimental.js
├── gitlab.com/
│   └── myorg/
│       └── myrepo/
│           └── v2.0.0/
│               └── build.js
└── git.company.com/
    └── team/
        └── project/
            └── main/
                └── build.js

Git URL Generation ​

Fabrik converts the remote recipe syntax to HTTPS Git URLs:

SyntaxGit URL
@tuist/recipes/build.jshttps://github.com/tuist/recipes.git
@gitlab.com/org/repo/script.jshttps://gitlab.com/org/repo.git
@git.company.com/team/project/build.jshttps://git.company.com/team/project.git

Cloning Behavior ​

  • Shallow Clone - Fabrik uses git clone --depth 1 for efficient fetching - only the latest commit is downloaded.
  • Cached After First Fetch - Once fetched, the recipe is cached locally. Subsequent runs reuse the cache without re-fetching.
  • Branch Tracking - When using a branch reference (e.g., @main), the cache is specific to that branch. Switching branches fetches a new copy.

Common Patterns ​

Local Development, Remote Production ​

bash
# During development - iterate on local recipe
fabrik run build.js

# In CI/production - use versioned remote recipe
fabrik run @myorg/recipes/build.js@v1.0.0

Versioned Releases ​

bash
# Production - use stable release
fabrik run @tuist/recipes/build.js@v1.0.0

# Development - use latest from main
fabrik run @tuist/recipes/build.js@main

Monorepo with Multiple Recipes ​

bash
# Different recipes in same repo
fabrik run @org/recipes/ci/build.js
fabrik run @org/recipes/ci/test.js
fabrik run @org/recipes/deploy/staging.js
fabrik run @org/recipes/deploy/production.js

Multi-Environment Recipes ​

bash
# Select environment via recipe path
fabrik run @company/infra/deploy/dev.js
fabrik run @company/infra/deploy/staging.js
fabrik run @company/infra/deploy/prod.js

Quick Reference ​

TypeSyntaxExample
Local recipefabrik run <file.js>fabrik run build.js
Remote (GitHub)fabrik run @org/repo/file.jsfabrik run @tuist/recipes/build.js
Remote with versionfabrik run @org/repo/file.js@tagfabrik run @tuist/recipes/build.js@v1.0.0
Remote (GitLab)fabrik run @gitlab.com/org/repo/file.jsfabrik run @gitlab.com/myorg/recipes/build.js
Remote (Self-hosted)fabrik run @host/org/repo/file.jsfabrik run @git.company.com/team/project/build.js

Next Steps ​