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
  • Config files
  • New desk
  • Glob
  • Publishing
  • Resources
Edit on GitHub
  1. Build on Urbit
  2. App School II (Full-Stack)

8. Desk and glob

With our React app now complete, we can put together the final desk and publish it.

Config files

So far we've written the following files for the back-end:

ourfiles
├── app
│   └── journal.hoon
├── lib
│   └── journal.hoon
├── mar
│   └── journal
│       ├── action.hoon
│       └── update.hoon
└── sur
    └── journal.hoon

There's a handful of extra files we need in the root of our desk:

  • desk.bill - the list of agents that should be started when our app is installed.

  • sys.kelvin - the kernel version our app is compatible with.

  • desk.docket-0 - configuration of our app tile, front-end glob and other metadata.

We only have one agent to start, so desk.bill is very simple:

:~  %journal
==

Likewise, sys.kelvin just contains:

[%zuse 414]

The desk.docket-0 file is slightly more complicated:

:~
  title+'Journal'
  info+'Dear diary...'
  color+0xd9.b06d
  version+[0 1 0]
  website+'https://urbit.org'
  license+'MIT'
  base+'journal'
  glob-ames+[~zod 0v0]
==

The fields are as follows:

  • %title is the name of the app - this will be displayed on the tile and when people search for the app to install it.

  • %info is a brief description of the app.

  • %color - the RGB hex color of the tile.

  • %version - the version number of the app. The fields represent major, minor and patch version.

  • %website - a link to a website for the app. This would often be its Github repo.

  • %license - the license of for the app.

  • %base - the desk name of the app.

  • %glob-ames - the ship to retrieve the front-end files from, and the hash of those files. We've put ~zod here but this would be the actual ship distributing the app when it's live on the network. The hash is 0v0 initially, but once we upload the front-end files it will be updated to the hash of those files automatically. Note that it's also possible to distribute front-end files from a separate web server. In that case, you'd use glob-http rather than glob-ames. The Glob documentation covers this alternative approach in more detail.

Our files should now look like this:

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

New desk

Next, we'll create a new %journal desk on our ship by forking an existing one. Once created, we can mount it to the unix filesystem.

In the Dojo of a fake ship:

|new-desk %journal
|mount %journal

Now we can browse to it in the unix terminal:

cd /path/to/zod/journal

Currently it just contains some skeleton files, so we need to delete those:

rm -rI /path/to/zod/journal/*

Apart from the kernel and standard library, desks need to be totally self-contained, including all mark files and libraries necessary to build them. For example, since our app contains a number of .hoon files, we need the %hoon mark, and its dependencies. The easiest way to ensure our desk has everything it needs is to copy in the "dev" versions of the %base and %landscape desks. To do this, we first clone the Urbit and Landscape git repositories:

git clone https://github.com/urbit/urbit.git urbit-git
git clone https://github.com/tloncorp/landscape.git landscape-git

If we navigate to the /pkg directory in the cloned /urbit repo:

cd /path/to/urbit-git/pkg

...we can combine the /base-dev and Landscape /desk-dev desks with the included symbolic-merge.sh script:

./symbolic-merge.sh base-dev journal
./symbolic-merge.sh ../../landscape-git/desk-dev journal

Now, we copy the contents of the new /journal folder into our empty desk:

cp -rL journal/* /path/to/zod/journal/

Note we've used the L flag to resolve symbolic links.

We can copy across all of our own files too:

cp -r /path/to/ourfiles/* /path/to/zod/journal/

Finally, in the dojo, we can commit the whole lot:

|commit %journal

Glob

The next step is to build our front-end and upload the files to our ship. If you haven't yet downloaded the journal front-end source files, you can grab them from their repository. In the folder containing our React app (/journal-app/ui relative to the repository base directory), we can run:

npm run build

This will create a /build directory containing the compiled front-end files. To upload it to our ship, we need to first install the %journal desk. In the dojo:

|install our %journal

Next, in the browser, we navigate to the %docket globulator at http://localhost:8080/docket/upload (replacing localhost with the actual host):

We select our %journal desk, then we hit "Choose file", and select the whole /build directory which was created when we build our React app. Finally, we hit "glob!" to upload it.

(For real production apps, you might prefer to use the -make-glob thread in the %landscape desk. This allows you to publish the glob from somewhere other than your ship; if your ship publishing the app is down, anyone can install the desk from a peer and get the frontend glob from this other location.)

If we now return to the homescreen of our ship, we'll see our tile displayed, and we can open our app by clicking on it:

Publishing

The last thing we need to do is publish our app, so other users can install it from our ship. To do that, we just run the following command in the dojo:

:treaty|publish %journal

Resources

  • App publishing/distribution documentation - Documentation covering third party desk composition, publishing and distribution.

  • Glob documentation - Comprehensive documentation of handling front-end files.

  • Desk publishing guide - A step-by-step guide to creating and publishing a desk.

  • -make-glob guide

Previous7. React app logicNext9. Summary

Last updated 1 day ago