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.
- To use Ruby within the body that gets rendered via Svelte the Ruby method needs to be a
$global var. This is not needed if you just want to use Ruby within the<script>tag. - I still need to explore how to use gems and other Ruby code.
- Further testing is needed as I only did basic tests so far.
- Also since it isn't natively supported if you use something like VSCode then your IDE will probably yell at you.
- Ruby in script tags.
- Ruby that transpiles to Ruby via opal.
- Returned back to Svelte in something it can read.
- Publish as
npmpackage. - Support .rb files including server side; ex:
+page.server.rb. - Compile to wasm?
- Allow usage of RubyGems?
v1.0.0
- Had to reorganize folders.
- Published npm package;
npm install @ruby-on-svelte/adapter. - Added
@ruby-on-svelte-adapterfolder, this is the actual npm package that is published. - The
@ruby-on-sveltefolder is what's being used in this template.
init commit
- Ruby in script tags:
<script lang="ruby">and<script lang="rb">are supported. - Ruby transpiles to JavaScript via Opal, then is returned back for the Svelte compiler.
- Two-way store sync, doing anything that's changes in Ruby by Svelte updates and vise versa.
- Handles non-browser env slightly better.
- JavaScript naming/collision handling slightly better.
- Added some error handling on Svelte side too.
- A bit of polish on the compiler.
- Better structure for future improvements.
- Beautified this
README.mdso its not basic af.
Excluding the ./@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
opal-compiler
svelte
sveltejs/kit
sveltejs/adapter-node
node
vite
mdsvex
eslint
prettier
typescript
tailwindcss
tailwindcss/forms
tailwindcss/typography- Install with npm:
npm i @ruby-on-svelte/adapter(adds this and the opal-compiler) - In your
svelte.config.jsfile 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()
],
...
};- Install
opal-compilervianpm(orpnpm installoryarn). - Put
./@ruby-on-sveltewherever you want. - And again, in your
svelte.config.jsfile 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_relativedoesn't work right now. - But
requiredoes:- If you DO NOT use
loadPathsyou should have the full path listed:require 'src/lib/modules/ruby/hello' - If you DO use
loadPathsyou can shorten that to this:require 'hello'
- If you DO NOT use
- To use the bare
requirestatements, add the directories you want on Opal's load path when wiring the adapter withinsvelte.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
importstatements to pull in.rbsources. So you have to use Ruby'srequire. If that global like$nameis defined in a required file, add a# @store $namein 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.