Tutorial: 5-minute blog (2018 November)

2019 Feb 27: The tutorial is now diverged. The first half is still good. The second half (about links) is no longer useful. For now you can check out the final result here.
Time commitment: about 2 mins per slide, times 30 slides.
This tutorial covers 80% of what there is to know about Hyperfiddle. The rest can be figured out as you go. @dustingetz in Slack with questions! Does this tutorial suck? @dustingetz with suggestions of how to make it good!
The simplest full app you can make in Hyperfiddle is a blog, which takes about 300 seconds. Half of that time is writing two Datomic queries with some minor schema modeling. The rest is fiddling around with Reagent renderers. Here is the final result. The equivalent as a proper Clojure project boilerplate involves git, compilers, build tools, setup Datomic, http web service, browser entrypoint, routing, client/server data sync, asynchronous http requests, node server rendering, deploy, etc. All stuff you simply don't have to think about anymore.
Below, we explode the hyperfiddle creation process, one thought at a time. Once you understand how the primitives compose together, you will be able to zip through this process in real-time.

Go to http://tank.hyperfiddle.net and make your first fiddle

Please namespace your fiddles with your username since the tank is a shared environment.
Read the tooltip on :fiddle/ident to see the docstring and that it is a keyword

Click stage to redirect to new fiddle

All fiddles are URL addressable, the fiddle/ident is in the URL

Set :fiddle/type to :query

Pause to read the tooltip on :fiddle/type and :fiddle/query.
This is the default query just so you have a working starting point, :db/add is a Datomic meta-attribute

Change the :fiddle/query: add :dustingetz.post/title to the where clause.

By convention, all schema attributes should be namespaced to the responsible maintainer.
This tutorial is coded against :dustingetz.post ontology (a related set of attributes), instead of making your own new attributes, because data is more interoperable if there are fewer ontologies shared by many datasets.

Forms and tables are automatically driven by your query and Datomic schema

The tooltip shows us that :published-date is an :instant, which is why the default cell renderer is a datepicker.

Schema editor

We don't need to create schema in this tutorial since the :dustingetz.post ontology is already installed into $ (the default database), but you can view it here.

Staging area

Nobody else can see your changes until you transact them. The stage is backed by browser localstorage. You can edit the stage by hand, including clear it out or paste any valid Datomic transaction.

Specify the pull columns, these drive the table

The table has three columns because the pull specifies three columns. Table cell widget types are reflected from Datomic schema (you can inspect schema in the label tooltip).

ClojureScript renderer

Tip: To restore the default renderer, you can delete your :fiddle/renderer and then blur the field.
val and ctx are in lexical scope.
Copy/paste this for your renderer. No (ns (:require ...)) yet, so you must fully qualify all namespaces e.g. cljs.pprint/pprint.

Better renderer

Tip: Auto-indent a codemirror with Cmd-A Shift-Tab
Destructuring [e] on line 6 corresponds with the shape of the Datomic query. Don't forget to turn your date into a string, and handle nil dates!
Copy/paste this for your renderer

Switch to EDN view to see the result directly, and then change the :fiddle/query to simplify the result shape

EDN view lets us see the result directly. The top image has an extra level of nesting (Datomic's Find Relation syntax vs Find Collection syntax)
Tip: Auto-indent a codemirror with Cmd-A Shift-Tab

Changing the result shape broke the custom :fiddle/renderer!

This error is not your fault! The :fiddle/renderer assumed the old result shape.

Switch to data view to ignore the :fiddle/renderer

Hand-coded :fiddle/renderer can break. Data view ignores :fiddle/renderer, so you can fix it

Repair the renderer

:fiddle/cljs-ns lets us defn

All fiddles have a ClojureScript namespace available inside your :fiddle/renderer as user. No deps.edn yet.

Data view comes with builtin admin links (hypermedia controls)

2019 Feb 27: Everything below this point has changed, todo rewrite this
Links in Hyperfiddle accomplish the same things that links on the web do. Like HTML, Hyperfiddle has three categories of links:
  • anchors
  • buttons
  • iframes
Here we see an anchor and a button, repeated over the resultset. The tooltip explains what link we're hovering.

This :hf/self link will take you to an admin UI for the entity named in the tooltip

The entity identifier is encoded into the URL

To edit or link to an entity, you need to pull :db/id or :db/ident

This is because it is not possible to address an entity (in URL or Datomic transaction) unless we have a way to name the entity. We don't automatically account for lookup refs (:db.unique/identity) yet, but that will work soon!

Customise :hf/self at the :fiddle/links editor

Staging this change is going to make the :hf/self link invalid

Make it valid by affixing a new fiddle to the link

This anchor takes us to the new fiddle now

Note the URL bar. Also notable is that the ID is not passed in the URL, nor is it in the tooltip. This is a bug in how fiddle defaults are computed! Navigate the link and we will see more.

Here is the new fiddle, change :fiddle/type to :pull

The URL is wrong now because d/pull requires an argument

Arguments to the Datomic query (or pull) are passed through the URL by position.

Go back to index with browser back button

The link parameters are properly reflected in the tooltip and URL now, because the target fiddle/type is specified.

Navigate again now that the link is fixed (fixme)

Data view displays the route, which is the EDN representation of what is in the URL. All fiddles are routable and URL addressable.

Set an explicit pull (in the empty entity case, this is used to render a blank form)

Why use :fiddle/markdown for the post content? By reusing the hyperfiddle builtin attributes for markdown, we are setting ourselves up to doing something clever. Attributes have semantic meaning in Datomic and we can use semantics to make a lot of things happen automatically. More about that in a guide, just go with it for now.

Toggle back to :view and render the post markdown

Press back button to go back to the blog index and wire up the links in the :fiddle/renderer

This boilerplate sucks. We have cleanup to do here. hyperfiddle.ui/link takes three parameters: :link/class (to select a link), ctx, and prompt string. ctx contains metadata and is managed by the runtime as we traverse the Datomic resultset and browse the fiddle graph.


Tighten up the CSS if you want

New blog post – the data view auto-links are sufficient here, don't need a custom view

When you pull * "splat" we render this free-form attribute entry field. The value is EDN, so you must e.g. quote strings. The ID is an auto-generated tempid, and it will turn positive when you blur a field to indicate that the entity now exists in this database value. Hyperfiddle popovers signal a "branch" using datomic.api/with – no datoms are actually staged until you click stage.

Customize the new-blog-post form by overriding the link :hf/new

Use your name for the fiddle/ident, not mine. There are presently seven builtin choices for :link/rel, you've now seen two of them (:hf/self and :hf/new). They are listed in the :link/rel tooltip.

The link is backed by your new fiddle now, we need to drill down and specify the form

Alt-click any pink-box to drill down (navigate deeper in a new tab)

Alt-clicking the popover opened a second tab

Specify the pull

Close the tab to go back, and try :hf/new again

your changes are safe in localstorage and synced across all tabs. Now you have an admin tool for your blog!

Automatically add today's date to all new blog posts:

1. (defmethod txfn)

Append more statements to the form's Datomic transaction.

2. Name the txfn in a :link/txfn

Associate the txfn with the :hf/new link, the txfn will be called when the popover is staged.

Try it, make sure it works!

You can always look at the stage to see what Datomic transactions were generated.

Transact the stage – all of our work is still in localstorage, nobody can see it until you transact

In production, there is no staging area and auto-transact is always on

Production – edit your URL "hyperfiddle.net" to "hyperfiddle.com"

Prod is a progressive web app with server side rendering and a built-in CDN. All fiddles are URL addressable and compatible with server-side rendering to any initial state. Once React.js attaches to the page, Hyperfiddle will navigate client-side, render client-side and hydrate data like a single-page app. All client/server data-sync has a time-basis on the request and is served Cache-Control: Immutable. Server rendered page HTML responses do not have a time-basis so they are served Cache-Control: max-age=1, s-maxage=300. We set s-maxage to hack around thundering herds for now. There is more work to be done here. Further reading: reddit comment


  1. Getting Started
  2. Overview
  3. Tutorial
    1. Simple blog
    2. Seattle
  4. Concepts
    1. Design
    2. Technology Vision
    3. Data model
    4. Semantics
    5. Staging area
    6. I/O Runtime
    7. Transactions
    8. Foreign integrations
    9. ctx
  5. Guides
    1. Links
    2. Transactions
    3. Dependent queries
    4. Iframes
    5. Select options
    6. Semantic admin console
    7. hyperfiddle.ui
    8. Markdown
    9. CSS
    10. Users and permissions
    11. Migrations
    12. Bulk import
  6. Triage
    1. Architecture braindump
    2. Technical braindumps
    3. hyperfiddle.jar