The usual path
- Pick a stack and wire all the basics
- Invent an admin UI nobody wants to maintain
- Build plumbing until the domain has somewhere to live
- Keep solving the same platform problems
The product comes last.


A TypeScript framework for platforms and portals
Build your software on a frame that is already there
Plugins keep domain logic modular. Workbench is the admin surface – a lot of the portal is already done.
yarn create raclette-appOpen source, self-hostable, built in Europe. Not 1.0 yet.
raclette.plugin.ts
import type { PluginMetadata } from "@raclettejs/core"
export default {
name: "community-hub/events",
author: "community-hub",
version: "0.1.0",
description:
"Domain plugin: meetups, sessions, and RSVPs for the community hub",
} satisfies PluginMetadatabackend/index.ts
import type { PluginFastifyInstance, PluginOptions } from "@raclettejs/core"
import { createEventModels } from "./event.model"
import { registerEventRoutes } from "./routes"
import { createEventService } from "./event.service"
export default async (
fastify: PluginFastifyInstance,
_opts: PluginOptions,
) => {
const models = createEventModels(fastify)
fastify.custom.eventService = createEventService(models.event)
await fastify.register((instance) =>
registerEventRoutes(instance, fastify.custom.eventService),
)
}frontend/widgets/EventManagementWidget.vue
<script setup lang="ts">
import EventFilters from "../components/EventFilters.vue"
import EventCard from "../components/EventCard.vue"
import RsvpPanel from "../components/RsvpPanel.vue"
const { $data, $i18n } = usePluginApi()
const { data: events, refresh } = $data.event.listUpcoming({
options: { immediate: true },
})
const selectedId = ref<string | null>(null)
</script>
<template>
<section class="event-management">
<header>
<h2>{{ $i18n.t("events.management.title") }}</h2>
<EventFilters @change="refresh" />
</header>
<div class="event-management__grid">
<EventCard
v-for="event in events"
:key="event._id"
:event="event"
:active="selectedId === event._id"
@select="selectedId = event._id"
/>
</div>
<RsvpPanel
v-if="selectedId"
:event-id="selectedId"
@updated="refresh"
/>
</section>
</template>Or start from a runtime – and spend your energy on the product.
The product comes last.
The product comes last.
Common patterns stay effortless. Custom logic stays powerful.
You can structure software by function – routes, models, screens – or by domain. racletteJS is domain-first: one business idea in one plugin.
Within a plugin we recommend a layout called the Golden Path – like a game's default difficulty: how the developers intended it to be played. If you want it hard, you are free to structure it as you want.
Domain first
Folders named after the business, not after HTTP verbs.
Golden Path inside
Recommended layout within a plugin. Optional, but that is the intended use.
Reuse over reinvent
Write a plugin once and lift it into your next project – or release it via NPM and share it with the community!
Explorer
A community management platform on racletteJS
Profiles, roles, and who belongs – the membership domain for the hub.
3 of 4 plugins enabled
There is no real plugin catalog yet. npm packages already work; a browsable shelf is still ahead. We are constantly working an the framework itself, but also on useful plugins for our users.
Community overview
Switch pages in the rail. Click a tile to see who owns it.
Don't get called just to move a block.
Give your users – or your client – a way to help themselves. They get a UI that fits how they work. You get time back, and it feels better on their side too.
A strong platform or portal UI thrives on flexibility. Letting people see content the way they want is something we always aim for – which is why we rely on a widget strategy. Not only different pages in the same frame, but sharing the same page, the same UI, so it feels integrated.
The frontend already ships a lot of widget behaviour, and it is still growing. You build with it while you develop; later, admins or power users can adjust the layout themselves – in The Workbench.
Don't write yet another admin dashboard.
The Workbench is the admin surface that ships with racletteJS – where those widgets get composed into real screens.
Create and adjust the UI without rebuilding an ops console from scratch. Manage users, tune plugin settings, and keep shaping the product after ship. Operators arrange the screen. You ship the plugin.
Real screenshots in the docsTitle
Description
Tags
Pathname
Slot Layout
Fun fact: The Workbench is itself written in racletteJS and therefore pluggable as well!
Docker-native. Easy to deploy.
You get Docker support out of the box – not as a later chore for production, but as how the app actually runs. Hook the build into the CI you already use and put it on a host you own. Self-host is the normal path.
yarn devContainerization already begins locally – right during development. Same environment as production, fewer “works on my machine” surprises.
yarn buildPrepares what CI turns into images. Drop them into the pipeline and deploy – keep your default hosting strategy.
Where to find it, what you can build with it, and where to talk about it.
We're a relatively new community with real values for a better tech future. Come say hello. We're glad you're here, and it should be fun.
Not a toy demo – the billing dashboard we run, built on racletteJS. Repo is public.
…/openstack-billingdashboard