---
slug: "railstart"
source_type: "readme"
source_url: "https://cdn.jsdelivr.net/gh/dpaluy/railstart@master/README.md"
repo: "https://github.com/dpaluy/railstart"
source_file: "README.md"
branch: "master"
---
# Railstart

[![Gem Version](https://img.shields.io/gem/v/railstart)](https://rubygems.org/gems/railstart)
[![Documentation](https://img.shields.io/badge/docs-rubydoc.info-blue.svg)](https://rubydoc.info/gems/railstart)
[![CI](https://github.com/dpaluy/railstart/actions/workflows/ci.yml/badge.svg)](https://github.com/dpaluy/railstart/actions/workflows/ci.yml)

Interactive CLI wizard for generating Rails 8 applications with customizable configuration and smart defaults.

Think of it as `rails new` with an opinion and a friendly interactive experience.

Requires Ruby 3.2 or newer. Development and release tooling use Ruby 4.0.5.

## Installation

```bash
gem install railstart
```

## Usage

### Quick Start

```bash
# Generate config files (optional, for customization)
railstart init

# Generate a new Rails app
railstart new my_app

# Or run without arguments for help
railstart
```

This launches an interactive wizard that guides you through Rails app setup:

```
Which database?
1) SQLite (default)
2) PostgreSQL
3) MySQL
> 2

Which CSS framework?
1) Tailwind (default)
2) Bootstrap
3) Bulma
4) PostCSS
5) None
> 1

Which JavaScript bundler?
1) Importmap (default)
2) esbuild
3) Webpack
4) Rollup
> 1

Skip any features?
(space to select, enter when done)
‣ ⓞ Action Mailer
  ⓞ Action Mailbox
  ⓞ Action Text
  ...

Generate API-only app?
> No

... (more questions) ...

Summary
════════════════════════════════════════
App name: my_app
Database: postgresql
CSS: tailwind
JavaScript: importmap
Skipped: (none)
API: No
════════════════════════════════════════

Proceed with app generation? Yes

Running: rails new my_app --database=postgresql --css=tailwind ...

Creating Rails app...
✨ Rails app created successfully at ./my_app
```

### Use Presets

Presets are configuration overlays that let you define different defaults and even different questions/post-actions for specific use cases.

**Important:** When you use `--default` without `--preset`, Railstart automatically applies the `default` preset (from `~/.config/railstart/presets/default.yaml` or the gem's built-in version). This means defaults may differ from the base `rails8_defaults.yaml` config.

**Modes:**
- **Interactive** (default): prompts for each question from the config schema
- **With --default**: skips questions, loads "default" preset, shows summary and confirms
- **With --preset**: loads specified preset as config overlay (can be interactive or with --default)

```bash
# Interactive mode (builtin defaults)
railstart new my_app

# Non-interactive with "default" preset (asks no questions, shows summary + confirms)
# Note: --default automatically loads the "default" preset (user or gem)
railstart new my_app --default

# Interactive with custom preset
railstart new my_app --preset api-only

# Non-interactive with custom preset
railstart new my_app --preset api-only --default
```

**Create custom presets** at `~/.config/railstart/presets/my-preset.yaml`:

Presets use the same YAML schema as config files - they can override question defaults, change choices, add new questions, or modify post-actions:

```yaml
# ~/.config/railstart/presets/api-only.yaml
# Presets merge on top of user config (and built-in config)
questions:
  - id: database
    choices:
      - name: PostgreSQL
        value: postgresql
        default: true  # Different default for this preset

  - id: api_only
    default: true  # Override default to true for API preset

post_actions:
  - id: init_git
    enabled: false  # Disable git init for this preset
```

Then use it:

```bash
# Interactive with api-only config
railstart new my_app --preset api-only

# Non-interactive with api-only config
railstart new my_app --preset api-only --default
```

## Creating Custom Presets

Presets are powerful tools for defining opinionated Rails configurations for specific stacks or team standards.

### Quick Preset Creation

Create a new preset file in `~/.config/railstart/presets/{name}.yaml`:

```yaml
---
# My Team Preset - PostgreSQL + Tailwind + Importmap

questions:
  - id: database
    choices:
      - name: PostgreSQL
        value: postgresql
        default: true

  - id: css
    choices:
      - name: Tailwind
        value: tailwind
        default: true

  - id: javascript
    choices:
      - name: Importmap
        value: importmap
        default: true
        rails_flag: "--javascript=importmap"

post_actions:
  - id: init_git
    enabled: true
```

Then use it:

```bash
# Interactive mode - prompts for each question
railstart new myapp --preset my-team

# Non-interactive mode - uses all preset defaults
railstart new myapp --preset my-team --default
```

### Built-in Presets

Railstart includes several ready-to-use presets:

- **`default`** - PostgreSQL + Tailwind + Importmap (sensible defaults)
- **`api-only`** - Minimal Rails for JSON APIs (no views, no frontend)
- **`vite-bun`** - Modern SPA with Vite + Bundlebun

### Example YAML Files

This repository also includes copyable YAML examples in `examples/`:

- `examples/config.yml` - global defaults for `~/.config/railstart/config.yaml`
- `examples/presets/api-postgresql.yml` - JSON API service with PostgreSQL
- `examples/presets/standard-postgresql.yml` - full-stack PostgreSQL app
- `examples/presets/minimal-sqlite.yml` - lightweight local prototype app
- `examples/presets/vite-bun.yml` - Vite, Bun, Tailwind, and PostgreSQL
- `examples/presets/template-action.yml` - template post-action reference

Use a preset example directly by passing its path:

```bash
railstart new my_app --preset ./examples/presets/standard-postgresql.yml --default
```

Or copy one into your user presets directory:

```bash
cp examples/presets/standard-postgresql.yml ~/.config/railstart/presets/standard-postgresql.yml
railstart new my_app --preset standard-postgresql --default
```

## Configuration

### Initialize Configuration Files

The easiest way to get started with custom configuration is to generate template files:

```bash
railstart init
```

This creates:
- `~/.config/railstart/config.yaml` - Minimal example containing only a few global overrides
- `~/.config/railstart/presets/` - Directory for your presets
- `~/.config/railstart/presets/example.yaml` - Example preset to get started

Keep `config.yaml` minimal so future built-in choices and flags continue to reach your installation. The full shipped schema remains available in `config/rails8_defaults.yaml`, while `examples/config.yml` provides a larger copyable example.

### Built-in Defaults

Railstart ships with sensible Rails 8 defaults defined in `config/rails8_defaults.yaml`. These drive the interactive questions and their defaults.

### Customize for Your Team

You can create `~/.config/railstart/config.yaml` manually or use `railstart init` to generate a minimal starting point. Add only the defaults you want to change:

```yaml
# After running `railstart init`, config.yaml contains a few example overrides.
# Keep only the overrides you want to apply to every run:

questions:
  - id: database
    default: postgresql

post_actions:
  - id: bundle_install
    enabled: false  # Disabled - your team manages gems differently

  - id: setup_auth
    name: "Setup authentication"
    enabled: true
    command: "bundle exec rails generate devise:install"  # New custom action
```

**Merge behavior:**

- User config (at `~/.config/railstart/config.yaml`) overrides built-in config
- By `id`: questions and post-actions are merged by their unique `id`
- If you override a question's `choices`, the entire choice list is replaced
- New questions/actions are appended in order

### Configuration Schema

#### Questions

```yaml
questions:
  - id: database                    # unique identifier
    type: select|multi_select|yes_no|input
    prompt: "User-facing question"
    help: "Optional inline help text"
    default: value_or_true_or_false
    
    # For select/multi_select
    choices:
      - name: "Display name"
        value: "internal_value"
        default: true              # at most one per select
        rails_flag: "--flag=%{value}"
    
    # For yes_no/input
    rails_flag: "--flag"            # or --flag=%{value}
    
    # Optional: only ask if condition is met
    depends_on:
      question: other_question_id
      value: expected_value
```

**Question types:**

- `select` - Single choice; returns scalar value
- `multi_select` - Multiple choices; returns array
- `yes_no` - Boolean; returns true/false
- `input` - Free text; returns string

#### Post-actions

```yaml
post_actions:
  - id: my_action                   # unique identifier
    name: "Human readable name"
    enabled: true                   # can be disabled
    command: "shell command to run"
    
    # Optional: prompt user before running
    prompt: "Run this action?"
    default: true
    
    # Optional: only run if condition is met
    if:
      question: question_id
      equals: value                 # or includes: [array, values]
```

#### Template Post-Actions

Post-actions can now execute full Rails application templates (including [RailsBytes scripts](https://railsbytes.com)) instead of plain shell commands.

```yaml
post_actions:
  - id: apply_tailwind_dash
    name: "Apply Tailwind dashboard template"
    type: template
    enabled: false             # keep disabled unless you trust the source
    prompt: "Run the sample template?"
    source: "https://railsbytes.com/script/zAasQK"
    variables:
      app_label: "internal-tools"  # optional instance variables available inside template
```

Key differences from `command` actions:

- Set `type: template` and provide a `source` (local path or URL). Railstart streams that template into Rails' own `apply` helper, so all standard DSL commands (`gem`, `route`, `after_bundle`, etc.) are available.
- `variables` is optional; when present, its keys become instance variables accessible from the template (e.g., `@app_label`). Railstart always exposes `@app_name` and `@answers` for convenience.
- Template actions still honor `prompt`, `default`, and `if` just like command actions. Keep remote templates disabled by default unless you explicitly trust them.

## Development

### Setup

```bash
# Install the required Ruby version
mise install ruby@4.0.5

# Install dependencies
bundle install

# Or use the setup script
bin/setup
```

### Testing the CLI

```bash
# Test the executable during development
bundle exec exe/railstart new my_app
bundle exec exe/railstart new my_app --default

# Interactive console for experimenting
bin/console
# Then in IRB:
# Railstart::CLI.start(["new", "my_app"])

# Install locally to test as a real gem
gem build railstart.gemspec
gem install railstart-[version].gem
railstart new my_app
```

### Running Tests

```bash
# Run tests
bundle exec rake test

# Lint code
bundle exec rubocop

# Lint and auto-fix
bundle exec rubocop -a

# Full check
bundle exec rake test && bundle exec rubocop && bundle exec rake yard && gem build railstart.gemspec
```

## Architecture

### Three-Layer Configuration System

Railstart merges configuration from three sources (in order):

1. **Built-in config**: `config/rails8_defaults.yaml` (shipped with gem)
2. **User config**: `~/.config/railstart/config.yaml` (optional global overrides)
3. **Preset** (optional): `~/.config/railstart/presets/NAME.yaml` (per-run overlay)

Each layer can:
- Override question defaults
- Replace choice lists entirely (by question ID)
- Add new questions
- Add/modify post-actions
- Enable/disable post-actions

Merging is by `id` for both `questions` and `post_actions`, allowing surgical overrides without duplicating entire configs.

### Core Components

- **Generator** (`lib/railstart/generator.rb`) - Orchestrates interactive flow
- **Command Builder** (`lib/railstart/command_builder.rb`) - Translates answers to `rails new` flags
- **CLI** (`lib/railstart/cli.rb`) - Thor command interface with `--preset` option

## AI Agent Skill

Railstart ships with an agent skill at `.agents/skills/railstart-coder/` for Codex- and Claude-style coding agents. The skill is structured as a lean `SKILL.md` plus focused reference files covering CLI usage, config layering, preset authoring, template post-actions, and gem development.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/dpaluy/railstart.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

Supported by [Majestic Labs](https://majesticlabs.dev/).
