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
  • Text editors
  • Development ships
  • Creating a fake ship
  • Fake ship networking
  • Local Networking
  • Faster fake ship booting
  • Working with desks
  • Mount a desk
  • Create a new desk
  • /*-dev folders
  • Project organization
  • Desk skeleton
Edit on GitHub
  1. Build on Urbit

Environment Setup

This guide covers best practices for preparing your environment to develop within the Urbit ecosystem.

Text editors

A variety of plugins have been built to provide support for the Hoon language in different text editors. These are listed below.

Note: The hoon compiler expects Unix-style line endings (LF) and will fail to parse Windows-style line endings (CRLF). Make sure your editor is set to use LF for line endings, especially if you're developing on Windows.

Sublime Text

Sublime Text is closed-source, but may be downloaded for free and there is no enforced time limit for evaluation. It runs on all major operating systems. It is available here.

Visual Studio Code

Visual Studio Code is free and open-source and runs on all major operating systems. It is available here. Hoon support may be acquired in the Extensions menu within the editor by searching for Hoon.

Emacs

Emacs is free and open-source and runs on all major operating systems. It is available here. Hoon support is available with hoon-mode.el.

Vim

Vim is free and open-source and runs on all major operating systems. It is available here. Hoon support is available with hoon.vim.

Development ships

Creating a fake ship

To do work with Hoon, we recommended using a "fake" ship — one that's not connected to the network.

Because such a ship has no presence on the network, you don't need an Azimuth identity. You just need to have installed the Urbit binary.

To create a fake ship named ~zod, run the command below. You can replace zod with any valid Urbit ID.

./urbit -F zod

This will take a couple of minutes, during which you should see a block of boot messages, starting with the Urbit version number.

Fake ship networking

Fake ships on the same machine can automatically talk to one another. Having created a fake ~zod, you can create a fake ~bus the same way:

./urbit -F bus

Now in the fake ~bus's dojo, try:

> |hi ~bus
>=
hi ~bus successful

Local Networking

Fake ships run on their own network using fake keys and do not communicate with live-net ships in any way. Multiple fake ships running on the same machine can network with each other. They don't need to have a "realistic" chain of fake sponsors to communicate.

Faster fake ship booting

While working with Hoon, you'll often want to delete an old fake ship and recreate a fresh one. Rather than having to wait a few minutes for the fresh ship to be initialized, you can instead create a backup copy of a fake ship. That way you can just delete the current copy, replace it with the backup, and reboot in a matter of seconds.

To do this, boot a fresh fake ship like usual, but with a different name:

./urbit -F zod -c zod.new

Once it's finished booting, it's a good idea to mount its desks so you don't have to do it again each time. In the Dojo:

> |mount %base
>=
> |mount %landscape
>=

Next, shut the ship down with Ctrl+D. Then, copy the pier and start using the copy instead:

cp -r zod.new zod
./urbit zod

Now whenever you want a new fake ~zod, you can just shut it down and do:

rm -r zod
cp -r zod.new zod
./urbit zod

Working with desks

If you're just working in the dojo or experimenting with generators, committing to the %base desk on a fake ship is fine. If you're working on a Gall agent or developing a desk for distribution, you'll most likely want to work on a separate desk and it's slightly more complicated.

Mount a desk

To mount a desk to Unix so you can add files, you just need to run the |mount command in the dojo and specify the name of the desk to mount:

|mount %base

The desk will now appear in the root of your pier (zod in this case):

zod
└── base

You can unmount it again by running the |unmount command in the dojo:

|unmount %base

Create a new desk

To create a new desk, you can just run:

|new-desk %mydesk

If you run |mount %mydesk, you'll see a /mydesk directory in your pier with the following files:

mydesk
├── mar
│   ├── hoon.hoon
│   ├── kelvin.hoon
│   ├── noun.hoon
│   └── txt.hoon
└── sys.kelvin

The mark files in /mar are for handling some basic filetypes, and sys.kelvin specifies which kernel version(s) the desk is compatible with. The |new-desk generator populates sys.kelvin with the current kernel version like [%zuse 410].

You can delete these files, copy in your own and run |commit %mydesk in the Dojo.

/*-dev folders

The files included by |new-desk are the only the bare minimum necessary to mount the desk. If you're building a full app, you'll almost certainly need a number of mark files and libraries from the %base and %landscape desks. If your app is going to talk to other apps on your ship, you'll likely need files for those, too.

To make these dependencies easier, the convention is for developers to include the necessary files in a separate /*-dev folder in their git repo:

  • The urbit/urbit repo includes a base-dev folder with the files necessary for interacting with agents on the %base desk, among other useful marks and libraries.

  • The tloncorp/landscape repo includes a desk-dev folder with marks and libraries for building Landscape apps.

You can clone these repos and copy the contents of their /*-dev folders into your own projects. A better alternative is to use the desk skeleton described below.

Project organization

When you're developing a desk, it's best to structure your working directory with the same hierarchy as a real desk. For example, ~/project-repo/desk might look like:

desk
├── app
│   └── foo.hoon
├── desk.bill
├── desk.docket-0
├── lib
│   └── foo.hoon
├── mar
│   └── foo
│       ├── action.hoon
│       └── update.hoon
├── sur
│   └── foo.hoon
└── sys.kelvin

That way, whenever you want to test your changes, you can just copy it across to your pier like:

cp -ruv desk/* /path/to/fake/zod/mydesk

And then just commit it in the dojo:

|commit %mydesk

If you're using dev folders as a base, it's best to keep those files separate from your own code.

Desk skeleton

Dependency management can be inconvenient when building Urbit apps. If you manually copy in /base-dev and Landscape's /desk-dev, it can be annoying to update them when a new kernel version is released.

For this reason, the Urbit Foundation has published a desk skeleton to use for new projects. It includes a couple of tools to make code organization and dependency management easier.

You can git clone the repo from urbit/desk-skeleton:

git clone https://github.com/urbit/desk-skeleton.git my-project

Then you can create a my-project repo on your Github, set the upstream to that instead, and push it:

cd my-project
git remote set-url origin https://github.com/YOUR-GITHUB/my-project.git
git push

The desk skeleton contains a /desk folder with an extremely simple example app. You can delete the /app/example.hoon file, add your own files, list your own agents in desk.bill, and add your own Docket configuration to desk.docket-0.

You can optionally create a separate /desk-dev folder for any dependencies another developer would need, or you can just put everything in /desk.

You'll notice /desk doesn't include /base-dev or Landscape's /desk-dev files. Instead, they're configured in peru.yaml and pulled in by peru. Peru is a Python app for managing dependencies. You can install it from:

  • pip: pip install peru

  • Homebrew: brew install peru

  • The AUR if you use Arch Linux

With peru installed on your system, you simply need to run ./build.sh. It'll create a /dist folder, copy in all the files from the /desk folder (and /desk-dev if it exists), and copy in the files from /base-dev and Landscape's /desk-dev on Github. The /dist folder will now contain all the necessary files, and you can copy them across to a mounted desk on a fake ship and |commit them in the Dojo.

The ./build.sh script can be run again any time you make changes.

If there's a kernel update down the line and you need to update the /base-dev and Landscape dependencies, you just need to run peru reup. This will update peru.yaml to use the latest commit on the master branch of the urbit/urbit and tloncorp/landscape GitHub repos. Then you can just run ./build.sh again.

The default peru.yaml only includes the two dependencies mentioned, but you can easily add any others you need. Refer to the peru documentation configuration details.

PreviousContentsNextHoon School

Last updated 1 day ago