This is a minimal example that uses Opal to be able to add Ruby code from the script section of a Svelte file.
I decided since there's interest, I'm going to build this out into an actual Ruby adapter for Svelte.
$ global var. This is not needed if you just want to use Ruby within the <script> tag.npm package.+page.server.rb.v1.0.0
npm install @ruby-on-svelte/adapter.@ruby-on-svelte-adapter folder, this is the actual npm package that is published.@ruby-on-svelte folder is what's being used in this template.init commit
<script lang="ruby"> and <script lang="rb"> are supported. README.md so its not basic af. ./@ruby-on-svelte folder the rest of this is just a minimal starter template using npx sv create and is a sveltejs/adapter-node.Run npm install (or pnpm install or yarn).
Then npm run dev or npm run dev -- --open
devDependencies:opal-compiler
svelte
sveltejs/kit
sveltejs/adapter-node
node
vite
mdsvex
eslint
prettier
typescript
tailwindcss
tailwindcss/forms
tailwindcss/typography
npm i @ruby-on-svelte/adapter (adds this and the opal-compiler)svelte.config.js file add this as a preprocess (the import needs to be wherever you put the folder) and I'm not sure yet if it matters where you put it in the preprocess list:import { RubyOnSvelte } from '@ruby-on-svelte/adapter';
...
const config = {
preprocess: [
...
RubyOnSvelte()
],
...
};
opal-compiler via npm (or pnpm install or yarn)../@ruby-on-svelte wherever you want.svelte.config.js file add this as a preprocess (the import needs to be wherever you put the folder) and I'm not sure yet if it matters where you put it in the preprocess list:import { RubyOnSvelte } from './@ruby-on-svelte/adapter/index.js';
...
const config = {
preprocess: [
...
RubyOnSvelte()
],
...
};
<script lang="ruby">
# Pound sign for comments since it treats it was Ruby.
# Example One
$count = 0
def increment
$count += 1
end
# Example Two
$name = "Ruby on Svelte"
# Does actually print to browser console/terminal.
puts "Hello, #{$name}!"
</script>
<main>
<p> Hello {$name}! </p>
<button on:click={increment}> Count: {$count} </button>
</main>
Unfortunately require_relative doesn't work right now.
But require does:
loadPaths you should have the full path listed:
require 'src/lib/modules/ruby/hello'loadPaths you can shorten that to this:
require 'hello'To use the bare require statements, add the directories you want on Opal's load path when wiring the adapter within svelte.config.js:
import { RubyOnSvelte } from './@ruby-on-svelte/adapter/index.js';
...
const config = {
preprocess: [
RubyOnSvelte({
loadPaths: [
'src/lib/modules/ruby' // <- you can add root `./` if you want but its not needed.
]
})
]
...
};
Within you svelte file you'll have to assign the method(s) to a svelte store if using a Ruby global var, because the Ruby gets compiled before Vite/Svelte ever sees the JavaScript. So you can't use standard import statements to pull in .rb sources. So you have to use Ruby's require. If that global like $name is defined in a required file, add a # @store $name in the svelte component so the adapter knows to use it as a Svelte store.
<script lang="ruby">
require 'hello'
# @store $name // <- just add this before/after and should be `#` a pound sign needs to be added.
</script>
© 2025 Vallereya
All rights reserved.
Code and Contributions have MIT License.
See LICENSE for more information.