Try it in the browser
This is ritsu itself, compiled to wasm32 and running in this page: ritsu check over a whole
project, each file checked by its own language with what one language checks read by the next,
and each language's generator and page. Nothing is sent anywhere. The files you edit stay in
the browser.
A project here is a handful of files, one to a tab. Every time a file changes, the page hands all of
them to the module, which runs the command as it would run in a directory holding the same files:
ritsu check . for the project, and the generator or the page of the file that is open. The list
holds a small shop where every language meets, the examples of rulec and dandori, and an empty
project to start from one file of your own. The tests hold what this page answers to what the
ritsu binary prints and writes on the same files, word for word
(crates/ritsu/tests/playground.rs).
What to try
It opens on a small shop where ordering has just added a value to its contract:
ORDER_STATUS_RETURNED = 5; in proto/shop/v1/order.proto. Billing's rule imports that enum, the
requirement in requirements/billing.req names the rule's table, and the map names the rule as
billing's layer against ordering. One line in one file, and three languages say what it does to them.
- Read the findings. Each headline carries the tool that says it. rulec:
Enum order_status does not agree with OrderStatus in ../../proto/shop/v1/order.proto, with the value the rule does not have. yuen:rulec cannot answer for rulec "billing/rules/billing_need.rule" table decide, the end of a requirement it can no longer hash. sakai:The file billing/rules/billing_need.rule does not pass rulec's check, or cannot be read. Click where a finding is, such asbilling/rules/billing_need.rule:5, to go to that line. - Put it right in the contract. Take the line out of the
.proto, and every file passes. - Or put it right in the rule. Press undo my edits, and in
billing/rules/billing_need.ruleadd| returnedto the end of the enum. rulec now saysA value of the imported enum order_status has neither a row nor `default`. Add the row| returned | skip |undercancelled, and rulec passes; yuen then says the tablechanged after accounts looked at this link on 2026-10-04, and shows the row that is new. A rule that passes its check is not yet a rule someone has looked at. - Break the border between a workflow and a rule. In
ordering/rules/urgency.rule, rename the outputcarriertocourier, inoutputsand in the headers of the table and the examples. rulec passes. dandori, which reads the rule's outputs from rulec in the same process, says`urgency.outputs` has no field `carrier` (urgent, courier)on the two lines ofordering/ship_order.flowthat read it. - Generate. Open
ordering/ship_order.flowand press generate: what Temporal runs, in TypeScript, eight files. Pick Step Functions beside it, and nothing is written: the flow waits for an event sent to the workflow and cleans up inon cancel, which Step Functions cannot do, and its tasks name no connection to call the warehouse through. Every language that generates does it here: a rule its code in twelve languages, a calendar in five, the book its SQL and its clients, the map its Context Mapper CML, the requirements ReqIF or W3C PROV. - Open the page for people of a rule, a calendar, the book or the flow: the page for those who read to understand and check what the code is to carry out. It is laid out for a whole window, so it opens in a tab of its own; the Markdown each writes for a pull request is below the link.
A small shop, in Japanese in the list is the same project with Japanese names, and the same steps work there.
The examples of rulec and dandori
Under rulec: one rule in the list are the five rules rulec's own playground opened, and under dandori: a flow and the files it reads every flow dandori's playground opened, each in a project with what it reads (its rules, the descriptions of the APIs it calls, its child flow, its dates file and its book) at the paths it names them by. They are made from the files those pages were made from, rulec's corpus and dandori's examples, and the tests hold them to those files. This page lists the English versions, and the Japanese page the Japanese ones.
- Find the row a table lacks. The table with a row missing is the table on rulec's front page
without its last row. rulec does not say the table is incomplete: it names the input that falls
through,
An input that matches no row: Destination = Overseas, Weight = 2001g, and gives the shape of the row that closes it. The whole table has the row. Change<=2kgto<=6kgin it, and rulec saysOverlapping rows: the same input matches row 1 and row 2, with an input that matches both. - Read rules of other shapes. Tables in stages reads what one table decides in the next. A bigger rule has two lines out of the same inputs meet again further down, and its page for people is laid out in that shape. Walking a list takes a list whose length the caller decides, and the form on its page for people has an Add a row button.
- Put a first draft right, one error at a time. A first draft of the hotel booking, with
errors calls two rules and Stripe's API, and check finds four errors in it. The last says the
workflow can end while the PaymentIntent is still
processing, or back inrequires_payment_method, and gives the run that gets there. At the end of line 91, afterfail CardDeclined "The card was declined", addleaving pi: the workflow hands the PaymentIntent over as it is, and three errors are left. - Change a rule a flow calls. A flow's rules are files of its project, each in a tab of its own.
dandori's playground could only show them; here, change one, and the flow's check reads the rule
as you left it. A rule's page for people is what
rulec docrenders, and a case can be tried on it. - Build a version for its platform. Hotel booking · for Temporal opens on its flow; press
generate, and the list beside it starts on Temporal. Pick Step Functions, and nothing is written:
the version waits for Stripe's webhook as an event sent to the workflow and releases the hold in
on cancel, which Step Functions cannot do, and it names no EventBridge connection to call Stripe through and no Lambda function for the rule. Hotel booking · for AWS is the version written for it.
Start from one file
To try one rule or one flow of your own, pick An empty project in the list. It has no file yet,
so add a file is the way in: give the file a path that ends in the extension of its language
(fee.rule, order.flow, days.cal, stock.book, …), and paste the file into its tab. A file it
reads, such as a rule a flow calls, is one more file of the project, at the path the first one names
it by.
Share what you made
copy a link puts a link to the project as it stands into the address bar, and onto the clipboard
where the browser allows it. The link holds the project, the file that is open, which of check,
generate and the page for people is showing, the target, and every file you changed, added or
removed, packed into the link itself. Nothing is stored anywhere: whoever opens the link has the
same files in the same tabs, and undo my edits takes them back to the project as it opens. The
links dandori's playground gave, such as #flow=examples/hotel/temporal/hotel.flow&view=build, open
the same flow here.
What is not here
- geas. geas holds a claim by running the code it names, and a page starts no process. A
.geasfile here is read and its syntax checked, and then geas says it cannot start the program. - Running.
dandori run,chobo run, the scenarios,rulec verifyandreplayneed processes, servers and files of records. They are the command. - The network.
source fetchandoutdatedask e-Gov, the eCFR and the URLs a source names. - A Rust workspace in a map. sakai asks Cargo for the crates of a map's
code rust "…", and a page cannot run Cargo. - Writing into the project.
rulec fmtandyuen reviewchange the files they are given. Here nothing changes the files but you.
The module this page loads, playground/ritsu.wasm, is built from ritsu's code (MIT OR
Apache-2.0) and, like the ritsu binary, holds the work of others: names from Unicode CLDR
(Unicode-3.0), a table made from the WHATWG Encoding Standard (BSD-3-Clause), eight crates from
crates.io, and copies of laws for the examples of explain.
THIRD_PARTY_NOTICES gives where
each comes from and the text of its license or its terms. dandori's examples in the list carry
cut-down copies of Stripe's OpenAPI document and of the Smithy models of Amazon SNS and SQS,
under their own licenses
(crates/dandori/THIRD_PARTY_NOTICES.md).