Skip to content

Project Setup

This page covers the melange init wizard in detail: what each prompt does, how the starter templates differ, and how to customize the setup.

For the shortest path to a working setup, see Quick Start.

The Init Wizard

melange init

The wizard detects your project type and prompts for configuration values. If it finds a go.mod, it defaults to Go; if it finds a package.json (and no go.mod), it defaults to TypeScript. When both exist, Go takes precedence.

Wizard Prompts

The wizard collects these settings in order:

PromptDefaultDescription
Schema pathmelange/schema.fgaWhere to put your authorization model
Starter modelOrganization RBACPre-built schema template
Database URLpostgres://localhost:5432/mydbPostgreSQL connection string
Migration strategyBuilt-inHow schema changes are applied
Generate client code?Yes (if project detected)Whether to set up type-safe code generation

If you choose versioned migration strategy, you’ll also be asked:

PromptDefaultDescription
Migration output directorymigrations/Where to write versioned SQL files
File formatSplitSeparate up/down files, or combined
Migration name suffixmelangeSuffix for generated filenames

If you enable client code generation, you’ll also be asked:

PromptDefaultDescription
RuntimeAuto-detectedgo or typescript
Output directoryinternal/authz (Go) or src/authz (TypeScript)Where to write generated code
Package nameauthzGo package name (Go only)
ID typestringType for object/subject IDs: string, int64, uuid.UUID

Starter Templates

Four starter templates are available:

The default template. Models organizations with a role hierarchy and repositories with inherited permissions.

model
  schema 1.1

type user

type organization
  relations
    define owner: [user]
    define admin: [user] or owner
    define member: [user] or admin

type repository
  relations
    define org: [organization]
    define owner: [user]
    define admin: [user] or owner
    define can_read: member from org or admin
    define can_write: admin
    define can_delete: owner

Covers role hierarchies (owner > admin > member) and parent inheritance (member from org). A good starting point for SaaS applications with organizations, teams, and resources.

The Authorization Modelling guide covers additional relation patterns including exclusions, intersections, and wildcards.

Migration Strategies

The wizard asks you to choose how schema changes are applied to your database:

StrategyCommandDescription
Built-inmelange migrateConnects directly and applies SQL. Suited to solo projects, prototyping, and simple deployments.
Versionedmelange generate migrationProduces .sql files for your existing migration framework. Suited to teams, PR reviews, and CI/CD pipelines.

Built-in connects directly to PostgreSQL and applies SQL functions. It tracks changes via a melange_migrations table and skips unchanged schemas automatically.

Versioned produces timestamped .sql files (e.g., 20240315_melange.up.sql) that you apply with your existing migration tool (golang-migrate, Atlas, Flyway, etc.). This means schema changes go through code review in PRs like any other migration.

You can change strategies later by updating your config file. See Running Migrations for details on comparison modes and CI workflows.

Generated Config File

After running melange init, the generated config file looks like this:

database:
  url: postgres://localhost:5432/mydb
generate:
  client:
    id_type: string
    output: internal/authz
    package: authz
    runtime: go
schema: melange/schema.fga

With versioned migrations enabled:

database:
  url: postgres://localhost:5432/mydb
generate:
  client:
    id_type: string
    output: internal/authz
    package: authz
    runtime: go
  migration:
    format: split
    name: melange
    output: migrations/
schema: melange/schema.fga

Config File Placement

The config file location depends on your schema path:

  • Schema under melange/ (e.g., melange/schema.fga): config written to melange/config.yaml
  • Otherwise: config written to melange.yaml at the project root

Melange discovers config files by searching up from the current directory. See Configuration Reference for the full discovery order and all options.

Non-Interactive Mode

Use -y to accept all defaults without prompting:

melange init -y

Override individual values with flags:

melange init -y \
  --schema melange/auth.fga \
  --db postgres://prod:5432/app \
  --template doc-sharing \
  --migration-strategy versioned

Skip runtime dependency installation:

melange init -y --no-install

All Init Flags

FlagDescriptionDefault
-y, --yesAccept all defaults without prompting
--no-installSkip installing runtime dependencies
--schemaSchema file pathmelange/schema.fga
--dbDatabase URLpostgres://localhost:5432/mydb
--templateStarter model: org-rbac, doc-sharing, minimal, noneorg-rbac
--runtimeClient runtime: go, typescriptAuto-detected
--outputClient output directoryinternal/authz (Go), src/authz (TS)
--packageClient package name (Go only)authz
--id-typeClient ID type: string, int64, uuid.UUIDstring
--migration-strategyMigration strategy: builtin, versionedbuiltin
--migration-outputVersioned migration output directorymigrations/
--migration-formatVersioned migration format: split, singlesplit
--migration-nameVersioned migration name suffixmelange

Client Code Generation

When code generation is enabled, melange init installs the runtime dependency automatically:

  • Go: go get github.com/pthm/melange/melange
  • TypeScript: Detected package manager (bun > pnpm > yarn > npm) runs add @pthm/melange

To generate client code after setup:

melange generate client

This produces type-safe constants and constructors from your schema. For example, with Go:

import "myapp/internal/authz"

// Generated constants and constructors
allowed, err := checker.Check(ctx,
    authz.User("alice"),
    authz.RelCanRead,
    authz.Repository("42"),
)

The --filter option (configurable in generate.client.filter) lets you limit which relations are generated. For example, --filter can_ generates only relations starting with can_.

Next Steps