Introduction
RiotJS is getting popular but still lacking visibility compared to mastodons projects like Vue, React, and Angular.
However, Riot is my first choice when creating a front-end, here is why:
- Minimal learning curve, Small API, Close to HTML/JS standards, no magic tricks, it's accessible to everyone
- Performant and predictable
- "Everything you wished native the web components API looked like" mentioned on their website, and I do approve!
- Tiny build when gzipped (compared to other front-ends)
- Good documentation
The development tooling is quite broad, and one of my favourites is Vite. However, I can't find any documentation or tutorial to run Riot with Vite! Let's fix that together.
This tutorial will go through all the steps to create a counter; the final result:
If you want to look at the final code, the GitHub repository: https://github.com/steevepay/riotjs-vite-setup
Build and run Riot with Vite
Init and install packages
Create a new directory
mkdir riot-vite-setup && cd riot-vite-setup
Init the node project
npm init
Now you have to install the following npm packages:
npm install --save-dev riot vite rollup-plugin-riot
Rollup-plugin-riot
is a plugin that compiles Riot files within rollup processes. ViteJS uses Rollup under the hood as its default bundler for JavaScript modules. Without it, Riot can't be compiled and used by Vite.
Finally, create a Vite configuration file, vite.conf.mjs
:
import { defineConfig } from 'vite'
import riot from 'rollup-plugin-riot'
export default defineConfig({
root : process.cwd() + '/client',
plugins : [riot()],
build: {
minify : 'esbuild', /** https://vitejs.dev/config/build-options.html#build-minify */
target : 'esnext' /** https://vitejs.dev/config/build-options.html#build-target */
}
})
Option details:
-
root
: defines the project root directory (where index.html is located). In our case, it is located inclient
. -
target
: Browser compatibility target for the final bundle. -
minify
: Minify the final bundle,Esbuild
is 20 ~ 40x faster than Terser and only 1 ~ 2% worse compression. - Lean more about Vite configuration: https://vitejs.dev/config/
Base project
All the front-end code will be located in the client
directory. Let's create three files:
-
client/index.html
: entry point of your front-end, it will mount the Riot application -
client/index.riot
: Riot application -
client/c-button.riot
: Custom button component used by the application.
At this stage, the root directory should look like:
package.json
package-lock.json
vite.config.mjs
client/index.html
client/index.riot
client/c-button.riot
The client/index.html
is pretty basic. It imports and mounts the Riot application:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>RiotJS + ViteJS</title>
</head>
<body>
<div id="root"></div>
<script type="module">
/** Load riot.js **/
import * as riot from 'riot'
import App from './index.riot'
const mountApp = riot.component(App)
mountApp(document.getElementById('root'))
</script>
</body>
</html>
The client/index.riot
imports the custom button c-button
and defines three instances:
- one to increase the counter
- one to decrease the counter
- one to print the counter
<app>
<div>
<h1> Riotjs + ViteJS </h1>
<c-button> { state.total } </c-button>
<c-button primary="true" onclick={ () => update({ total: state.total + 1 }) }> Add </c-button>
<c-button danger="true" onclick={ () => update({ total: state.total - 1 }) }> Delete </c-button>
</div>
<script>
/** Load the custom button **/
import cButton from './c-button.riot';
export default {
/** Define the custom button **/
components : {
cButton
},
/** State of the counter **/
state : {
total: 0
}
}
</script>
</app>
The client/c-button.riot
contains a slot to change the text and props to change the style of the button (default/grey, primary/purple, or danger/orange):
<c-button >
<button class="btn{ props.primary ? ' btn-primary' : '' }{ props.danger ? ' btn-danger' : '' }">
<slot></slot>
</button>
</c-button>
Now we have everything to start a development server to get a preview of the app!
Run live preview
Start the development server, then access the live preview on http://localhost:5173/ :
npm run dev
Et voilà, you should be able to increase/decrease the counter 🎉 You can make code changes, and the preview will be refreshed automatically.
🛟 If you need any help, leave a comment.
Build for production
Build the front for production:
npm run build
Built files are located in the dist directory.
Conclusion
Using Vite makes the development of Riot application super easy:
- No-brain configuration
- efficient development server with HMR (Hot Module Replacement), allowing you to see changes in your code instantly without a full page reload
- efficient build system with tree-shaking
Thanks for reading! Cheers 🍻
Resources
- Link to the Github Repository Riot+Vite setup
- Good comparison between Riot and Vue
- Why Vite?
Top comments (5)
I almost missed this. Big fan of RiotJS. Might want to add the #riotjs tag
Although there does seem to be a maintained #riot tag, it appears all/most posts relating to it are under #riotjs. Maybe you should switch to that? Your post with the #riot tag appears to be the only one.
Also, could the dev team sort it out so #riotjs is the main tag for RiotJS? @michaeltharrington
Thanks so much for the call out, Jon!
We do indeed have some features to help us with this. There's a DEV feature called tag aliasing, where we can join two tags together, making one of the tags the main tag.
For instance, we've aliased
#js
to#javascript
, which resulted in 2 things:#js
to a post, we automatically files the post under#javascript
instead#js
(dev.to/t/js), you're going to be redirected to#javascript
(dev.to/t/javascript)Like you pointed out, most folks have congregated under
#riotjs
so I think it does make sense to alias#riot
to#riotjs
. Good suggestion! I'll also be in touch with the mod of#riot
to let them know about this adjustment.I just changed the tag, thank you!
Thanks Jon! I just added the #riot tag ;)
I'm a big fan too, and I plan to write more about creating advanced apps. Riot is underrated and lacking of communication/visibility.