If your code will display query results from a server, you will probably need to add at least one unit to your ns file.

You can ignore this section altogether if your template does not support dynamic data. (Or if your own code base does not use that capability.)


An ns.yml for an app contains the units section.

A unit is a building block for a dynamic UI. It's typically a query to the back end. Each unit contains:

  • a hierarchy of data types, where each data type appears only once.
  • possibly other key values used by specific templates.

Here's a typical unit specification in the ns.yml file:

    slug: Products
    highestComponent: Product
                  create#details: null
              create#location: null


The hierarchy is represented as an object with indentation to show levels, and where each key is a data type string.

Each data type string contains a prefix followed by a pound sign and then the name of the type. The prefix is the data function type.

Data Types

The value for each type is its children, or null if it has no children. So for instance, in this case a seller has products, which have specs that have details. In addition, products have locations where they are sold.

Data Function Types

The data function types tell what is to be done with the data type in the given unit. create typically means that the user has the right to create one. For instance, a product can be created for a seller in this case. Another common data function type is constrain. That means that the type is used to constrain the query, rather than showing up in the returned data. In this case, the seller is constraining the data returned, so that data will only show for a given selected seller.

Each data function type is defined by the template. Your template should contain a list of data function types that you can use. The template specifies types of files generated for each, and contains specific file templates that are used to generate them when you call ns generate -c $CODE.

Technically, a template could create any list of data function types. In practice, it would probably be the best practice to use some standard ones. {The geenee tool is new, and we have not yet resolved the issue.}

Template Specific Key Values.

The README of your template should tell you any additional required keys.

  • A slug may be used in some templates, for instance to create a filename.
  • The highestComponent also may be needed.

Building a Hierarchy

You can, of course, start simple and build up a hierarchy one step at a time. Any time you like, you can call ns generate and it will modify the code that you have so far to include changes to your units and their hierarchies. That will result in generated files for each type.

To create a hierarchy, think in terms of what you want to display. If for instance you expect to show a list of watches as the highest level of a UI unit, then your hierarchy should be rooted in watches. Maybe for each watch you will have a list of sellers.

                location: null
                hours: null
                phone: null
        cost: null

Look in the README file of your template for information about the types of elements used.

But if you want the sellers to be shown on the top with the watches that they carry, then you'd reverse that.

            location: null
            hours: null
            phone: null
                cost: null

You can extend a hierarchy as many levels deep as you like. When a type has no child types, it should receive the value of null.

Data Types

Note that nothing is stated in the hierarchy about data type. By default, everything is a string. Other types may be supported by specific templates and by various frameworks. For instance, the NoStack backend currently supports strings, numbers, booleans and sets.


In addition to the required hierarchy, a unit specification may also include a properties section that specifies various properties for data types. For instance, the following excerpt from an ns.yml file shows that for the type done the data type is boolean.

            dataType: boolean


More complex interfaces and queries can be built with joining units. A single hierarchy cannot show the same data type twice, which is limiting. But joins provide complete querying expressive power if the template is used for connecting to an actual backend.

A joins key can be added, as follows:

    from: type1__unit1
    to: type2__unit2

More documentation and functionality for joins is planned, but currently they are not the highest priority because they are actually handled by NoStack on the server side, and geenee is a more generic tool for templating. That said, we plan to add that functionality very soon to templates. A helper function could be created in the template that changes generated code based on the value of joins.