esbuild
esbuild Integration
Ruby2JS provides an esbuild plugin for fast builds of CLI tools, serverless functions, and other non-web projects. For web applications with hot module replacement, see the Vite integration instead.
Table of Contents
Installation
npm install esbuild-plugin-ruby2js ruby2js
Or install from the beta release:
npm install https://www.ruby2js.com/releases/esbuild-plugin-ruby2js-beta.tgz
npm install https://www.ruby2js.com/releases/ruby2js-beta.tgz
Basic Usage
// build.mjs
import * as esbuild from 'esbuild';
import ruby2js from 'esbuild-plugin-ruby2js';
await esbuild.build({
entryPoints: ['src/cli.rb'],
plugins: [ruby2js()],
bundle: true,
platform: 'node',
outfile: 'dist/cli.js'
});
# src/cli.rb
def main
args = process.argv.slice(2)
puts "Hello, #{args[0] || 'World'}!"
end
main
Run your build:
node build.mjs
node dist/cli.js Alice # => Hello, Alice!
Options
ruby2js({
// Filters to apply (default: ['Functions', 'ESM', 'Return'])
filters: ['Functions', 'ESM', 'Return', 'CamelCase'],
// ES level target (default: 2022)
eslevel: 2022,
// Patterns to exclude from transformation
exclude: ['vendor/'],
// Auto-export all top-level functions and classes
autoexports: true
})
See Options for the full list of Ruby2JS options.
Use Cases
CLI Tools
Write Node.js command-line tools in Ruby syntax:
# src/cli.rb
require 'fs'
require 'path'
def main
command = process.argv[2]
case command
when 'init'
fs.writeFileSync('config.json', '{}')
puts 'Initialized config.json'
when 'version'
puts '1.0.0'
else
puts "Usage: mycli [init|version]"
end
end
main
// build.mjs
await esbuild.build({
entryPoints: ['src/cli.rb'],
plugins: [ruby2js({ filters: ['Functions', 'CJS', 'Return'] })],
bundle: true,
platform: 'node',
outfile: 'dist/cli.js'
});
AWS Lambda
Write Lambda handlers in Ruby syntax:
# src/handler.rb
export async def handler(event, context)
name = event.dig(:queryStringParameters, :name) || 'World'
{
statusCode: 200,
body: JSON.stringify({ message: "Hello, #{name}!" })
}
end
// build.mjs
await esbuild.build({
entryPoints: ['src/handler.rb'],
plugins: [ruby2js()],
bundle: true,
platform: 'node',
target: 'node18',
outfile: 'dist/handler.js'
});
Build Scripts
Write custom build tools:
# scripts/generate.rb
require 'fs'
require 'path'
require 'glob'
def generate_index
files = glob.sync('src/**/*.rb')
content = files.map do |file|
name = path.basename(file, '.rb')
"export * from './#{file}'"
end.join("\n")
fs.writeFileSync('src/index.js', content)
puts "Generated index with #{files.length} exports"
end
generate_index
With tsup
tsup is a popular esbuild-based bundler for npm packages:
// tsup.config.js
import { defineConfig } from 'tsup';
import ruby2js from 'esbuild-plugin-ruby2js';
export default defineConfig({
entry: ['src/index.rb'],
esbuildPlugins: [ruby2js({ autoexports: true })],
format: ['esm', 'cjs'],
dts: false,
outDir: 'dist'
});
Comparison with Vite
| Feature | esbuild | Vite |
|---|---|---|
| Build Speed | Fastest | Fast |
| Hot Module Replacement | No | Yes |
| Dev Server | No | Built-in |
| Source Maps | No | Yes |
| Framework Presets | No | Yes |
Use esbuild for: CLI tools, Lambda functions, build scripts, backend services, npm packages.
Use Vite for: Web applications, SPAs, projects needing HMR and a dev server. See the Vite integration.
Next Steps
- Filters — Available transformation filters
- Options — All configuration options
- ESM Filter — ES module imports and exports
- CJS Filter — CommonJS require and exports