Skip to content

Recipes ​

Ready-to-paste specs for the things people build most. Each one is a complete spec.yaml: copy it (the button is in the top-right corner of the code), paste it into your project, and run npx openink dev. The preview next to it is the real output, so click around.

To combine recipes, copy the blocks under blocks: into a screen of your own. Every block and prop is listed in the block reference.

Charts ​

Bar chart ​

Pass your own numbers in values, or leave it out for sample data.

yaml
name: Sales report
theme: color
screens:
  - id: report
    blocks:
      - { type: h2, text: Monthly sales }
      - type: chart
        kind: bar
        h: 220
        label: Units sold
        values: [12, 19, 8, 24, 17, 30]   # your own numbers

Line or area chart ​

yaml
name: Traffic
theme: color
screens:
  - id: traffic
    blocks:
      - { type: h2, text: Visitors this week }
      - type: chart
        kind: line                         # or area
        h: 220
        tone: teal
        values: [120, 180, 150, 240, 210, 320, 290]

Pie and donut charts ​

yaml
name: Budget
theme: color
screens:
  - id: budget
    blocks:
      - { type: h2, text: Where the money goes }
      - type: grid
        children:
          - { type: chart, kind: pie, h: 180, label: Pie }
          - { type: chart, kind: donut, h: 180, tone: pink }

KPI cards ​

trend colours the change: up green (the default), down orange, flat grey.

yaml
name: KPIs
theme: color
screens:
  - id: kpis
    blocks:
      - type: grid
        cols: 4
        children:
          - { type: stat, label: Revenue, value: $48k, delta: +12% }
          - { type: stat, label: Orders, value: "1,204", delta: +5% }
          - { type: stat, label: Refunds, value: "18", delta: "+3", trend: down }
          - { type: stat, label: Rating, value: "4.8", delta: ±0, trend: flat }

For a whole dashboard with charts and a modal, see the one on the home page.

Forms ​

Login ​

go on the button opens another screen.

yaml
name: Acme
screens:
  - id: login
    width: narrow
    blocks:
      - type: card
        children:
          - { type: h1, text: Welcome back }
          - { type: input, label: Email, inputType: email }
          - { type: input, label: Password, inputType: password }
          - { type: checkbox, label: Remember me }
          - { type: button, label: Log in, primary: true, go: home }
          - { type: link, text: Forgot password?, toast: Link sent }
  - id: home
    blocks:
      - { type: alert, kind: success, text: You are logged in. }
Press Log in.Open ↗

Settings ​

yaml
name: Settings
theme: pastel
screens:
  - id: settings
    width: narrow
    blocks:
      - { type: h1, text: Settings }
      - { type: toggle, label: Email notifications, checked: true }
      - { type: toggle, label: Dark mode }
      - { type: select, label: Language, options: [English, Deutsch] }
      - { type: radio, label: Plan, options: [Free, Pro, Team], selected: 1 }
      - { type: slider, label: Volume, value: 60 }
      - { type: button, label: Save, primary: true, toast: Saved }
Toggles, the slider and the radio buttons all respond.Open ↗

Multi-step form ​

One screen per step, linked with go.

yaml
name: Onboarding
screens:
  - id: account
    width: narrow
    blocks:
      - { type: steps, items: [Account, Profile, Done], active: 0 }
      - { type: input, label: Email }
      - { type: button, label: Next, primary: true, go: profile }
  - id: profile
    width: narrow
    blocks:
      - { type: steps, items: [Account, Profile, Done], active: 1 }
      - { type: input, label: Full name }
      - { type: button, label: Finish, primary: true, go: done }
  - id: done
    width: narrow
    blocks:
      - { type: steps, items: [Account, Profile, Done], active: 2 }
      - { type: alert, kind: success, text: All set! }
      - { type: link, text: Start over, go: account }
Press Next, then Finish.Open ↗

Pages ​

Pricing cards ​

tone and fill on one card make it stand out.

yaml
name: Pricing
theme: color
screens:
  - id: pricing
    blocks:
      - { type: h1, text: Simple pricing }
      - type: grid
        cols: 3
        children:
          - type: card
            children:
              - { type: h3, text: Free }
              - { type: h2, text: $0 }
              - { type: list, items: [1 project, Community help] }
              - { type: button, label: Start, toast: Welcome! }
          - type: card
            tone: purple                   # highlight one plan
            fill: true
            children:
              - { type: badge, status: wait, text: Popular }
              - { type: h3, text: Pro }
              - { type: h2, text: $12 }
              - { type: list, items: [Unlimited projects, PDF export] }
              - { type: button, label: Buy Pro, primary: true }
          - type: card
            children:
              - { type: h3, text: Team }
              - { type: h2, text: $49 }
              - { type: list, items: [Everything in Pro, SSO] }
              - { type: button, label: Contact us }

Landing page ​

yaml
name: Lumen
theme: color
screens:
  - id: home
    blocks:
      - type: hero
        title: Plan trips together
        text: Shared maps, group votes and split bills in one app.
        tone: purple
        fill: true
        children:
          - { type: button, label: Get started, primary: true, toast: Hi! }
      - type: grid
        cols: 3
        children:
          - { type: card, title: Plan, children: [Drop pins on a map.] }
          - { type: card, title: Vote, children: [Pick dates together.] }
          - { type: card, title: Split, children: [Settle up in a tap.] }
Press Get started.Open ↗

Table with status badges ​

A cell can be text or any block, such as a badge or a button.

yaml
name: Orders
theme: color
screens:
  - id: orders
    blocks:
      - { type: search, placeholder: Search orders }
      - type: table
        columns: [Order, Customer, Status]
        rows:
          - ["#1042", Ana, { type: badge, status: on, text: Paid }]
          - ["#1041", Marc, { type: badge, status: wait, text: Pending }]
          - ["#1040", Lea, { type: badge, status: off, text: Refunded }]
      - { type: pagination, pages: 5, active: 1 }

Interaction ​

nav adds header buttons to every screen. go works on buttons, cards, links, table rows and tab-bar items.

yaml
name: Shop
nav:                                       # header buttons on every screen
  - { icon: home, label: Home, go: home }
  - { icon: cart, label: Cart, go: cart }
screens:
  - id: home
    blocks:
      - { type: h1, text: New arrivals }
      - type: card
        go: cart                           # the whole card is clickable
        children:
          - { type: image, h: 100, label: Blue shirt }
          - { type: h3, text: Blue shirt · $29 }
  - id: cart
    blocks:
      - { type: h1, text: Your cart }
      - { type: text, text: 1 × Blue shirt }
      - { type: button, label: Back to shop, go: home }
Click the card, then the header buttons.Open ↗

Confirm dialog ​

open shows a modal; close: true on a button inside it closes it again.

yaml
name: Files
screens:
  - id: files
    blocks:
      - { type: h2, text: report.pdf }
      - { type: button, label: Delete, icon: trash, tone: red, open: confirm }
modals:
  - id: confirm
    title: Delete this file?
    width: narrow
    children:
      - { type: text, text: This cannot be undone. }
      - type: row
        children:
          - { type: button, label: Delete, tone: red, close: true, toast: Done }
          - { type: button, label: Cancel, close: true }
Press Delete.Open ↗

Tabs ​

yaml
name: Product
screens:
  - id: product
    blocks:
      - { type: h2, text: Trail runner 2 }
      - type: tabs
        tabs:
          - label: Details
            children:
              - { type: image, h: 120, label: Photo }
              - { type: text, text: "Light, grippy and waterproof." }
          - label: Reviews
            children:
              - { type: rating, value: 4, text: (128 reviews) }
          - label: Shipping
            children:
              - { type: text, text: Free delivery in 2 days. }
Switch between the tabs.Open ↗

FAQ ​

yaml
name: Help
screens:
  - id: faq
    blocks:
      - { type: h2, text: Frequently asked questions }
      - type: accordion
        open: 0                            # first one starts open
        items:
          - label: How do I reset my password?
            children: [Use the link on the login page.]
          - label: Can I cancel any time?
            children: [Yes. Your plan runs until the period ends.]
          - label: Do you offer refunds?
            children: ["Within 14 days, no questions asked."]
Open and close the questions.Open ↗

Mobile ​

App in a phone frame ​

device draws a phone (or kind: tablet, kind: browser). A tabbar at the bottom links the screens.

yaml
name: Notes
theme: pastel
screens:
  - id: notes
    blocks:
      - type: device                       # phone frame
        children:
          - { type: h2, text: My notes }
          - { type: card, go: note, children: [Shopping list] }
          - { type: card, go: note, children: [Trip ideas] }
          - type: tabbar
            items:
              - { icon: home, label: Notes, go: notes }
              - { icon: plus, label: New, go: note }
  - id: note
    blocks:
      - type: device
        children:
          - { type: link, text: ← Back, go: notes }
          - { type: textarea, label: Shopping list, rows: 6 }
          - { type: button, label: Save, primary: true, go: notes }
Tap a note, then Save.Open ↗

Released under the MIT License.