Getting Started

Getting Started with Juntos

Install Juntos and run your first Rails app across multiple platforms.

Table of Contents

Prerequisites

  • Ruby 3.2+ and Rails 7+
  • Node.js 22+
  • Git

Installation

Add Juntos to your Rails app:

# Gemfile
gem 'ruby2js', require: 'ruby2js/rails'
bundle install

The bin/juntos command is available automatically.

Quick Start with a Demo

The fastest way to see Juntos in action is to run a demo app:

# Blog demo (CRUD, associations, validations)
curl -sL https://raw.githubusercontent.com/ruby2js/ruby2js/master/test/blog/create-blog | bash -s myapp

# Chat demo (real-time, Turbo Streams, Stimulus)
curl -sL https://raw.githubusercontent.com/ruby2js/ruby2js/master/test/chat/create-chat | bash -s myapp

See Demo Applications for detailed walkthroughs.

Run Modes

Juntos supports multiple ways to run the same Rails code:

Development Mode (Browser)

bin/juntos dev -d dexie

Runs in your browser with IndexedDB storage. Features:

  • Hot reload on file changes
  • Auto-migrations
  • Ruby debugging in DevTools
  • No server required

Server Mode (Node.js)

bin/juntos db:prepare -d sqlite
bin/juntos up -d sqlite

Runs on Node.js with SQLite. Also supports:

  • Bun: bin/juntos up -t bun -d sqlite
  • Deno: bin/juntos up -t deno -d postgres

Deploy Mode (Edge)

bin/juntos deploy -d neon     # Vercel Edge
bin/juntos deploy -d d1       # Cloudflare Workers

Builds and deploys to serverless platforms.

Database Adapters

Adapter Runtime Storage
dexie Browser IndexedDB
sqljs Browser SQLite/WASM
pglite Browser, Node PostgreSQL/WASM
sqlite Node, Bun SQLite file
pg Node, Bun, Deno PostgreSQL
neon Vercel Serverless PostgreSQL
d1 Cloudflare Edge SQLite

Development to Production Workflow

Configure different databases per environment in config/database.yml:

development:
  adapter: sqlite
  database: db/development.sqlite3

production:
  adapter: d1
  database: myapp_production

Then use environment flags:

# Local development (uses sqlite from database.yml)
bin/juntos up

# Prepare production database (creates D1, runs migrations)
bin/juntos db:prepare -e production

# Deploy to production (uses d1 from database.yml)
bin/juntos deploy -e production

The -e flag (or RAILS_ENV environment variable) selects which database.yml section to use. Commands read from database.yml by default; -d overrides the adapter if you need to.

Common patterns:

Development Production Use Case
sqlite d1 Cloudflare Workers
sqlite neon Vercel Edge
dexie dexie Browser-only (static hosting)
sqlite pg Traditional Node.js server

Using with an Existing App

Any Rails app can run with Juntos:

cd your-rails-app
bin/juntos dev -d dexie

If transpilation fails, check:

  1. Unsupported Ruby features (see What Works below)
  2. Gems that require native extensions
  3. Complex metaprogramming

What Works

Models

Try it — edit the Ruby to see how models transpile:

class Article < ApplicationRecord
  has_many :comments, dependent: :destroy
  belongs_to :author
  validates :title, presence: true
  validates :body, length: { minimum: 10 }

  after_create_commit { broadcast_append_to "articles" }
end

Associations, validations, and callbacks transpile directly.

Controllers

Try it — controllers transpile with the same patterns:

class ArticlesController < ApplicationController
  before_action :set_article, only: %i[show edit update destroy]

  def index
    @articles = Article.all
  end

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to @article
    else
      render :new, status: :unprocessable_entity
    end
  end
end

Standard CRUD patterns work without modification.

Views

<%= form_with model: @article do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body %>
  <%= f.submit %>
<% end %>

<%= link_to "Back", articles_path %>
<%= button_to "Delete", @article, method: :delete %>

ERB helpers transpile to JavaScript functions.

Routes

Rails.application.routes.draw do
  resources :articles do
    resources :comments
  end
  root "articles#index"
end

Nested routes and path helpers work as expected.

What Works Differently

Feature Rails Juntos
Migrations Run manually Auto-run in browser
Database Any ActiveRecord adapter Juntos-supported adapters
Background jobs Sidekiq, etc. Promises, setTimeout
Real-time Action Cable BroadcastChannel, WebSocket

What Doesn’t Work

  • Action Mailer — browsers can’t send SMTP
  • Runtime metaprogramming — no method_missing or define_method
  • Complex SQL — supports basic raw SQL conditions like where('updated_at > ?', timestamp), but complex joins and subqueries are not supported
  • Native gems — gems requiring C extensions
  • File uploads — no filesystem in browsers (use external storage)

Next Steps