Urbit Docs
  • What is Urbit?
  • Get on Urbit
  • Build on Urbit
    • Contents
    • Environment Setup
    • Hoon School
      • 1. Hoon Syntax
      • 2. Azimuth (Urbit ID)
      • 3. Gates (Functions)
      • 4. Molds (Types)
      • 5. Cores
      • 6. Trees and Addressing
      • 7. Libraries
      • 8. Testing Code
      • 9. Text Processing I
      • 10. Cores and Doors
      • 11. Data Structures
      • 12. Type Checking
      • 13. Conditional Logic
      • 14. Subject-Oriented Programming
      • 15. Text Processing II
      • 16. Functional Programming
      • 17. Text Processing III
      • 18. Generic and Variant Cores
      • 19. Mathematics
    • App School I
      • 1. Arvo
      • 2. The Agent Core
      • 3. Imports and Aliases
      • 4. Lifecycle
      • 5. Cards
      • 6. Pokes
      • 7. Structures and Marks
      • 8. Subscriptions
      • 9. Vanes
      • 10. Scries
      • 11. Failure
      • 12. Next Steps
      • Appendix: Types
    • App School II (Full-Stack)
      • 1. Types
      • 2. Agent
      • 3. JSON
      • 4. Marks
      • 5. Eyre
      • 6. React app setup
      • 7. React app logic
      • 8. Desk and glob
      • 9. Summary
    • Core Academy
      • 1. Evaluating Nock
      • 2. Building Hoon
      • 3. The Core Stack
      • 4. Arvo I: The Main Sequence
      • 5. Arvo II: The Boot Sequence
      • 6. Vere I: u3 and the Serf
      • 7. Vere II: The Loom
      • 8. Vanes I: Behn, Dill, Kahn, Lick
      • 9. Vanes II: Ames
      • 10. Vanes III: Eyre, Iris
      • 11. Vanes IV: Clay
      • 12. Vanes V: Gall and Userspace
      • 13. Vanes VI: Khan, Lick
      • 14. Vanes VII: Jael, Azimuth
    • Runtime
      • U3
      • Conn.c Guide
      • How to Write a Jet
      • API Overview by Prefix
      • C in Urbit
      • Cryptography
      • Land of Nouns
    • Tools
      • Useful Links
      • JS Libraries
        • HTTP API
      • Docs App
        • File Format
        • Index File
        • Suggested Structure
    • Userspace
      • Command-Line App Tutorial
      • Remote Scry
      • Unit Tests
      • Software Distribution
        • Software Distribution Guide
        • Docket File
        • Glob
      • Examples
        • Building a CLI App
        • Debugging Wrapper
        • Host a Website
        • Serving a JS Game
        • Ship Monitoring
        • Styled Text
  • Urbit ID
    • What is Urbit ID?
    • Azimuth Data Flow
    • Life and Rift
    • Urbit HD Wallet
    • Advanced Azimuth Tools
    • Custom Roller Tutorial
    • Azimuth.eth Reference
    • Ecliptic.eth Reference
    • Layer 2
      • L2 Actions
      • L2 Rollers
      • L2 Roller HTTP RPC-API
      • L2 Transaction Format
  • Urbit OS
    • What is Urbit OS?
    • Base
      • Hood
      • Threads
        • Basics Tutorial
          • Bind
          • Fundamentals
          • Input
          • Output
          • Summary
        • HTTP API Guide
        • Spider API Reference
        • Strandio Reference
        • Examples
          • Child Thread
          • Fetch JSON
          • Gall
            • Poke Thread
            • Start Thread
            • Stop Thread
            • Take Facts
            • Take Result
          • Main-loop
          • Poke Agent
          • Scry
          • Take Fact
    • Kernel
      • Arvo
        • Cryptography
        • Move Trace
        • Scries
        • Subscriptions
      • Ames
        • Ames API Reference
        • Ames Cryptography
        • Ames Data Types
        • Ames Scry Reference
      • Behn
        • Behn API Reference
        • Behn Examples
        • Behn Scry Reference
      • Clay
        • Clay API Reference
        • Clay Architecture
        • Clay Data Types
        • Clay Examples
        • Clay Scry Reference
        • Filesystem Hierarchy
        • Marks
          • Mark Examples
          • Using Marks
          • Writing Marks
        • Using Clay
      • Dill
        • Dill API Reference
        • Dill Data Types
        • Dill Scry Reference
      • Eyre
        • EAuth
        • Eyre Data Types
        • Eyre External API
        • Eyre Internal API
        • Eyre Scry Reference
        • Low-Level Eyre Guide
        • Noun channels
      • Gall
        • Gall API Reference
        • Gall Data Types
        • Gall Scry Reference
      • Iris
        • Iris API Reference
        • Iris Data Types
        • Iris Example
      • Jael
        • Jael API Reference
        • Jael Data Types
        • Jael Examples
        • Jael Scry Reference
      • Khan
        • Khan API Reference
        • Khan Data Types
        • Khan Example
      • Lick
        • Lick API Reference
        • Lick Guide
        • Lick Examples
        • Lick Scry Reference
  • Hoon
    • Why Hoon?
    • Advanced Types
    • Arvo
    • Auras
    • Basic Types
    • Cheat Sheet
    • Cryptography
    • Examples
      • ABC Blocks
      • Competitive Programming
      • Emirp
      • Gleichniszahlenreihe
      • Islands
      • Luhn Number
      • Minimum Path Sum
      • Phone Letters
      • Restore IP
      • Rhonda Numbers
      • Roman Numerals
      • Solitaire Cipher
      • Water Towers
    • Generators
    • Hoon Errors
    • Hoon Style Guide
    • Implementing an Aura
    • Irregular forms
    • JSON
    • Limbs and wings
      • Limbs
      • Wings
    • Mips (Maps of Maps)
    • Parsing Text
    • Runes
      • | bar · Cores
      • $ buc · Structures
      • % cen · Calls
      • : col · Cells
      • . dot · Nock
      • / fas · Imports
      • ^ ket · Casts
      • + lus · Arms
      • ; mic · Make
      • ~ sig · Hints
      • = tis · Subject
      • ? wut · Conditionals
      • ! zap · Wild
      • Constants (Atoms and Strings)
      • --, == · Terminators
    • Sail (HTML)
    • Serialization
    • Sets
    • Standard Library
      • 1a: Basic Arithmetic
      • 1b: Tree Addressing
      • 1c: Molds and Mold-Builders
      • 2a: Unit Logic
      • 2b: List Logic
      • 2c: Bit Arithmetic
      • 2d: Bit Logic
      • 2e: Insecure Hashing
      • 2f: Noun Ordering
      • 2g: Unsigned Powers
      • 2h: Set Logic
      • 2i: Map Logic
      • 2j: Jar and Jug Logic
      • 2k: Queue Logic
      • 2l: Container from Container
      • 2m: Container from Noun
      • 2n: Functional Hacks
      • 2o: Normalizing Containers
      • 2p: Serialization
      • 2q: Molds and Mold-Builders
      • 3a: Modular and Signed Ints
      • 3b: Floating Point
      • 3c: Urbit Time
      • 3d: SHA Hash Family
      • 3e: AES encryption (Removed)
      • 3f: Scrambling
      • 3g: Molds and Mold-Builders
      • 4a: Exotic Bases
      • 4b: Text Processing
      • 4c: Tank Printer
      • 4d: Parsing (Tracing)
      • 4e: Parsing (Combinators)
      • 4f: Parsing (Rule-Builders)
      • 4g: Parsing (Outside Caller)
      • 4h: Parsing (ASCII Glyphs)
      • 4i: Parsing (Useful Idioms)
      • 4j: Parsing (Bases and Base Digits)
      • 4k: Atom Printing
      • 4l: Atom Parsing
      • 4m: Formatting Functions
      • 4n: Virtualization
      • 4o: Molds
      • 5a: Compiler Utilities
      • 5b: Macro Expansion
      • 5c: Compiler Backend & Prettyprinter
      • 5d: Parser
      • 5e: Molds and mold builders
      • 5f: Profiling support
    • Strings
    • The Engine Pattern
    • Udon (Markdown-esque)
    • Vases
    • Zuse
      • 2d(1-5): To JSON, Wains
      • 2d(6): From JSON
      • 2d(7): From JSON (unit)
      • 2e(2-3): Print & Parse JSON
      • 2m: Ordered Maps
  • Nock
    • What is Nock?
    • Decrement
    • Definition
    • Fast Hints and Jets
    • Implementations
    • Specification
  • User Manual
    • Contents
    • Running Urbit
      • Cloud Hosting
      • Home Servers
      • Runtime Reference
      • Self-hosting S3 Storage with MinIO
    • Urbit ID
      • Bridge Troubleshooting
      • Creating an Invite Pool
      • Get an Urbit ID
      • Guide to Factory Resets
      • HD Wallet (Master Ticket)
      • Layer 2 for planets
      • Layer 2 for stars
      • Proxies
      • Using Bridge
    • Urbit OS
      • Basics
      • Configuring S3 Storage
      • Dojo Tools
      • Filesystem
      • Shell
      • Ship Troubleshooting
      • Star and Galaxy Operations
      • Updates
Powered by GitBook

GitHub

  • Urbit ID
  • Urbit OS
  • Runtime

Resources

  • YouTube
  • Whitepaper
  • Awesome Urbit

Contact

  • X
  • Email
  • Gather
On this page
  • Install binary
  • Spin up fake ship
  • Create desk
  • Copy in extra files
  • Mount the desk
  • Config files
  • sys.kelvin
  • desk.ship
  • desk.bill
  • desk.docket-0
  • Commit
  • Install
  • Create files for glob
  • Login to Landscape
  • Upload to glob
  • Publish
  • Remote install
Edit on GitHub
  1. Build on Urbit
  2. Userspace
  3. Software Distribution

Software Distribution Guide

In this document we'll walk through an example of creating and publishing a desk that others can install. We'll create a simple "Hello World!" front-end with a "Hello" tile to launch it. For simplicity, the desk won't include an actual Gall agent, but we'll note everything necessary if there were one.

Install binary

Note: You can skip this step if you already have the latest binary installed.

Follow the CLI install instructions appropriate for your OS to download the urbit binary.

Spin up fake ship

Note: You can skip this step if you already have a fake ~zod.

With the urbit binary installed, run the following in the terminal to spin up a fake ~zod:

Unix
./urbit -F zod

It will take a couple of minutes to spin up, but it should eventually take you to a Dojo prompt like:

Dojo
~zod:dojo>

Create desk

In the Dojo of your fake ~zod, run the following to create a new desk called %hello:

Dojo
|new-desk %hello

If you now run +tree on the desk, you'll see it now exists and has a handful of files in it:

Dojo
> +tree /=hello=
/mar/hoon/hoon
/mar/kelvin/hoon
/mar/noun/hoon
/mar/txt/hoon
/sys/kelvin

Copy in extra files

Each desk must be self-contained in terms of its mark files and libraries. There's a couple of extra mark files and such that we'll need to add, so run the following commands in the Dojo:

Dojo
|cp %/mar/mime/hoon /=hello=/mar/mime/hoon
|cp %/mar/txt-diff/hoon /=hello=/mar/txt-diff/hoon
|cp %/mar/ship/hoon /=hello=/mar/ship/hoon
|cp %/mar/bill/hoon /=hello=/mar/bill/hoon
|cp /=landscape=/mar/docket-0/hoon /=hello=/mar/docket-0/hoon
|cp /=landscape=/sur/docket/hoon /=hello=/sur/docket/hoon
|cp /=landscape=/lib/docket/hoon /=hello=/lib/docket/hoon

Mount the desk

Now we have all the basic files we need, we can mount the desk to the host. Run the following in the Dojo:

Dojo
|mount %hello

Now, in an ordinary terminal (not the Dojo), navigate to the mounted desk:

Unix
cd zod/hello

Config files

sys.kelvin

Our desk must include a sys.kelvin file which specifies the kernel version it's compatible with. The |new-desk generator automatically added that, so we can leave it as-is.

desk.ship

We can optionally add a desk.ship file to specify the original publisher of this desk. We're using a fake ~zod so let's just add ~zod as the publisher:

Unix
echo "~zod" > desk.ship

desk.bill

If we had Gall agents in this desk which should be automatically started when the desk is installed, we'd add them to a list in the desk.bill file. It would look something like this:

desk.bill
:~  %some-agent
    %another-agent
==

In this example we're not adding any agents, so we'll simply omit the desk.bill file.

desk.docket-0

The final file we need is desk.docket-0. This one's more complicated, so we'll open it in our preferred text editor:

Unix
nano desk.docket-0

In the text editor, we'll add the following:

desk.docket-0

:~  title+'Hello'
    info+'A simple hello world app.'
    color+0x81.88c9
    image+'https://media.urbit.org/guides/additional/dist/wut.svg'
    base+'hello'
    glob-ames+[~zod 0v0]
    version+[0 0 1]
    website+'https://urbit.org'
    license+'MIT'
==

You can refer to the Docket File documentation for more details of what is required. In brief, the desk.docket-0 file contains a hoon list of clauses which configure the appearance of the app tile, the source of the glob, and some other metadata.

We've given the app a %title of "Hello", which will be displayed on the app tile and will be the name of the app when others browse to install it. We've given the app tile a %color of #8188C9, and also specified the URL of an %image to display on the tile.

The %base clause specifies the base URL path for the app. We've specified 'hello' so it'll be http://localhost:8080/apps/hello/... in the browser. For the glob, we've used a clause of %glob-ames, which means the glob will be served from a ship over Ames, as opposed to being served over HTTP with a %glob-http clause or having an Eyre binding with a %site clause. You can refer to the glob documentation for more details of the glob options. In our case we've specified [~zod 0v0]. Since ~zod is the fakeship we'll install it on, the %docket agent will await a separate upload of the glob, so we can just specify 0v0 here as it'll get overwritten later.

The %version clause specifies the version as a triple of major version, minor version and patch version. The rest is just some additional informative metadata which will be displayed in App Info.

So let's save that to the desk.docket-0 file and have a look at our desk:

Unix
ls
desk.docket-0  desk.ship  lib  mar  sur  sys.kelvin

Commit

Now we've added out configuration files, we can commit them to the desk. Back in the fake ~zod's Dojo, run the following:

Dojo
|commit %hello

You should see something like this as the result:

Dojo
>=
+ /~zod/hello/9/desk/ship
+ /~zod/hello/9/desk/docket-0

Install

The next step is to install the desk as an app. Run the following in the Dojo:

Dojo
|install our %hello

You should see a message like:

Dojo
docket: awaiting manual glob for %hello desk

That's because our desk.docket-0 file includes a %glob-ames clause which specifies our ship as the source, so it's waiting for us to upload the glob of front-end files.

Create files for glob

We'll now create the files for the glob. We'll use a very simple static HTML page that just displayes "Hello World!" and an image. Typically we'd have a more complex JS web app that talked to apps on our ship through Eyre's channel system, but for the sake of simplicity we'll forgo that. Let's hop back in the Unix terminal and run a few commands:

Unix
cd ~
mkdir hello-glob
cd hello-glob
mkdir img
wget -P img https://media.urbit.org/guides/additional/dist/pot.svg

We should now have the following file structure in our home directory:

Unix
hello-glob
└── img
    └── pot.svg

We've grabbed an image to use in our "Hello world!" page. The next thing we need to add is an index.html file in the root of the folder. The index.html file is mandatory; it's what will be loaded when the app's tile is clicked. Let's open our preferred editor and create it:

Unix
nano index.html

In the editor, paste in the following HTML and save it:

index.html
<!DOCTYPE html>
<html>
  <head>
    <style>
      div {
        text-align: center;
      }
    </style>
  </head>
  <title>Hello World</title>
  <body>
    <div>
      <h1>Hello World!</h1>
      <img src="img/pot.svg" alt="pot" width="219" height="196" />
    </div>
  </body>
</html>

Our /hello-glob folder should now look like this:

Unix
hello-glob
├── img
│   └── pot.svg
└── index.html

Login to Landscape

Open a web browser and navigate to localhost:8080, or just localhost if port 8080 doesn't work. It should take you to the fake ~zod's login screen. Login with the fake ~zod's default code of lidlut-tabwed-pillex-ridrup.

Once you login, you'll notice you have the Hello app's tile, but it still says "installing" because we haven't uploaded the glob yet:

Upload to glob

We can now create a glob from the /hello-glob directory we previously created. To do so, navigate to http://localhost:8080/docket/upload in the browser. This will bring up the %docket app's Globulator tool:

Simply select "hello" from the drop-down, click "Choose file" and select the /hello-glob folder in the the file browser, then click the "glob!" button.

Now if we return to our ship's homescreen, we should see the tile looks as we specified in the docket file:

And if we click on the tile, it'll load the index.html in our glob:

Our app is working!

Publish

The final step is publishing our desk with the %treaty agent so others can install it. To do this, there's a simple command in the dojo:

Dojo
> :treaty|publish %hello
>=

Note: For desks without a docket file (and therefore without a tile and glob), %treaty can't be used. Instead you can make the desk public with |public %desk-name, which will enable other ships to install it with the Dojo command |install ~sampel %desk-name.

Remote install

Let's spin up another fake ship in the terminal so we can try install it:

Unix
cd ~
./urbit -F bus

In the browser, navigate to localhost:8081 (or localhost:8080 if that doesn't work) and login with ~bus's code riddec-bicrym-ridlev-pocsef. Next, type "~zod" in the search bar and click on the matching result. It should pop up a list of ~zod's published apps, which in this case is our "Hello" app:

When we click on the app, it'll show some of the information from the clauses in the docket file:

Click "Get App" and it'll ask as if we want to install it:

Finally, click "Get 'Hello'" and it'll be installed as a tile on ~bus which can then be opened:

PreviousSoftware DistributionNextDocket File

Last updated 1 day ago