Project

salvia_rb

0.0
The project is in a healthy, maintained state
A simple and clear Ruby web framework with ERB, SSR Islands, Tailwind, and ActiveRecord. No Node.js required.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 5.0
~> 0.1
~> 13.0
~> 1.6

Runtime

~> 3.0
~> 1.12
~> 6.0
~> 3.0
~> 2.0
~> 2.0
~> 1.3
~> 2.0
~> 0.23
~> 2.6
 Project Readme

Salvia 🌿

The Future of Rails View Layer

Salvia is a next-generation Server-Side Rendering (SSR) engine designed to replace ERB with JSX/TSX in Ruby on Rails. It brings the Islands Architecture and True HTML First philosophy to the Rails ecosystem.

Gem

Vision: The Road to Sage

Salvia is the core engine for a future framework called Sage (inspired by Express, Hono, and Oak). While Sage will be a complete standalone framework, Salvia is available today as a drop-in replacement for the View layer in Ruby on Rails.

Features

  • 🏝️ Islands Architecture: Render interactive components (Preact/React) only where needed. Zero JS for static content.
  • πŸš€ True HTML First: Replace app/views/**/*.erb with app/pages/**/*.tsx.
  • ⚑ JIT Compilation: No build steps during development. Just run rails s.
  • πŸ’Ž Rails Native: Seamless integration with Controllers, Routes, and Models.
  • πŸ¦• Deno Powered: Uses Deno for lightning-fast TypeScript compilation and formatting.

Requirements

  • Ruby 3.1+
  • Rails 7.0+ (Recommended)
  • Deno 1.30+ (Required for JIT compilation and tooling)

Installation

1. Install Deno

Salvia requires Deno. Follow the official installation guide.

# macOS / Linux
$ curl -fsSL https://deno.land/x/install/install.sh | sh

2. Add Gem

Add this line to your Rails application's Gemfile:

gem 'salvia'

And then execute:

$ bundle install

Getting Started

1. Setup Salvia

Run the interactive installer to set up Salvia for your Rails project:

$ bundle exec salvia install

This command will:

  1. Create the salvia/ directory structure.
  2. Generate deno.json (Single Source of Truth for dependencies).
  3. Cache Deno dependencies to ensure fast startup.
  4. Configure Rails to automatically include Salvia::Helpers (providing the ssr method).

Directory Structure

salvia/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ components/  # Shared UI components (Buttons, Cards)
β”‚   β”œβ”€β”€ islands/     # Interactive components (Hydrated on client)
β”‚   └── pages/       # Server Components (SSR only, 0kb JS to client)
└── deno.json        # Dependency management (Import Map)

2. Create a Page (Server Component)

Delete app/views/home/index.html.erb and create salvia/app/pages/home/Index.tsx:

import { h } from 'preact';

export default function Home({ title }) {
  return (
    <div class="p-10">
      <h1 class="text-3xl font-bold">{title}</h1>
      <p>This is rendered on the server with 0kb JavaScript sent to the client.</p>
    </div>
  );
}

3. Render in Controller

In your Rails controller:

class HomeController < ApplicationController
  def index
    # Renders salvia/app/pages/home/Index.tsx
    render html: ssr("home/Index", title: "Hello Salvia")
  end
end

4. Add Interactivity (Islands)

Create an interactive component in salvia/app/islands/Counter.tsx:

import { h } from 'preact';
import { useState } from 'preact/hooks';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount(count + 1)} class="btn">
      Count: {count}
    </button>
  );
}

Use it in your Page:

import Counter from '../../islands/Counter.tsx';

export default function Home() {
  return (
    <div>
      <h1>Interactive Island</h1>
      <Counter />
    </div>
  );
}

5. Turbo Drive (Optional)

Salvia works seamlessly with Turbo Drive for SPA-like navigation.

Add Turbo to your layout file (e.g., salvia/app/pages/layouts/Main.tsx):

<head>
  {/* ... */}
  <script type="module">
    import * as Turbo from "@hotwired/turbo";
    Turbo.start();
  </script>
</head>

Since dependencies are managed in deno.json, you don't need to write full URLs.

Core Concepts: Pages vs Islands

Understanding the separation of concerns is crucial for "True HTML First" development.

Feature Pages (Server Components) Islands (Client Components)
Path salvia/app/pages/ salvia/app/islands/
Environment Server (Ruby/QuickJS) Client (Browser)
Interactivity ❌ Static HTML βœ… Interactive (Event Listeners)
State ❌ Stateless βœ… Stateful (Signals/Hooks)
Browser APIs ❌ No (window, document are mocked) βœ… Yes
Usage Layouts, Initial Data Fetching Forms, Modals, Dynamic UI

Documentation

  • English:
    • Wisdom for Salvia: Deep dive into the architecture, directory structure, and "True HTML First" philosophy.
    • Reference Guide: Comprehensive guide on usage, API, and configuration.
    • Architecture: Internal design of the gem.
  • Japanese (ζ—₯本θͺž):
    • README: ζ—₯本θͺžη‰ˆREADME。

Framework Support

Salvia is primarily designed for Ruby on Rails to pave the way for the Sage framework.

  • Ruby on Rails: First-class support.

Zero Config Architecture

Salvia v0.2.0 adopts a Zero Config philosophy.

  • deno.json is SSOT: It manages dependencies for both Server (SSR) and Client (Browser).
  • Auto Import Map: npm: specifiers in deno.json are automatically converted to esm.sh URLs for the browser.
  • No Build Config: build.ts and sidecar.ts are managed internally, but you can extend globals via salvia.globals in deno.json.

Production & CI

In production environments (e.g., Docker, Heroku, Render):

  1. Deno is required: Ensure Deno is installed in your build/runtime environment.
  2. Build Step: Run bundle exec salvia build during deployment.
    • This bundles Islands, generates Import Maps, and builds Tailwind CSS.
    • It generates hashed filenames for cache busting.
    • Note: While Salvia uses JIT compilation in development for a "No Build" experience, salvia build pre-compiles assets for production to ensure zero runtime compilation overhead.

License

The gem is available as open source under the terms of the MIT License.