{:.} nest_ (v1.1.2)



nest is a language of touch for objects by monome

nest helps you build a touchable user interface for a norns script, and provides the means to hook up that interface to whatever sound engine or musical process you’d like to interact with (a synth engine, a softcut looper, a lua sequencer, midi output, crow voltages & i2c). you’re welcome to think about nest as a full-blown library, a markup language, or a maiden-scriptable application in the vein of teletype’s grid ops.

it works by splitting up an interface (grid, arc, or norns itself) into any number of lego pieces called affordances, each with a unique value and unique behaviors configured through properties. these lego blocks can then be bound to your musical process using custom action functions (much like the params system). affordances are organized inside special tables called nests which help group your affordances and allow them to communicate with each other and with the hardware itself. a basic snippet of nest code might look a bit like this:

nest_ {
    my_affordance = _affordance {
        property = 5,
        value = 1,
        action = function(self, value)


studies assume a basic knowledge of lua and the norns system. the format should feel very familiar to norns studies proper, each progresses on basic concepts and concludes with a simple musical piece on the grid (if you’re using norns gridless, see below note on compatibility).

  1. nested affordances
  1. multiplicity

  2. affordance overview

  1. state & meta-affordances



while a norns by itself is technically the only requirement for nest_, it tends to prove more useful when building interfaces with lots of input (grid, grid + norns, or grid + arc + norns). norns after all, just has three keys and two encoders, so many musical ideas can be expressed cleanly without this sort of system, and you get some more flexibility as a bonus (see the examples in norns studies, if you haven’t already). if you want to get a feel for the sort of textual norns interfaces the txt module can be used for, feel free to skip ahead to study 3.


install via the maiden project manager, in the community catalog


been working on the current iteration of nest_ most days for about 6 months, and I’ve been iterating on various forms in max for about three years, ever since I first got my grid. super excited to finally share the magic of nesting w/ the world : )


been loving the soft drop of the youtube clips popping up :slight_smile: very happy for you and excited to dive more into these and see what other people do with them. feels like it opens up new portals to norns’ infinite potential. thank you for your gifts.


thank you ! happy to add to the large gift stack of norns potential

<< a small bump to say that the links to the studies where broken, and I have fixed said links >>


regardless of your familiarity with code plz feel free to ask questions here or via PM ! I don’t imagine this thing to be unconfusuing to anybody, happy to talk more and get into further specifics : )


Study 4 blew me away - thank you. Study 4 should be a standalone script all by itself with w/ FM synth support for the 8 parameters as an option. @vicimity seriously check this out and you will see what i mean.


in video four the switch between the sequencer and the playing by hand is beautiful

an exercise for the reader ; ) ; ) ; )

my surprise was that adding this feature to the script involved not adding anything to the script


Wonderful work, and great documentation. Can’t wait to dig in!

1 Like

Blew me away also! Went ahead and made a midi / w/syn version of this study. Not sure if I’m done or I should start adding stuff on top… For anyone who wants to play here is the repo.

In params you can choose output, scale and root note. There are also cc mappings in there. Default is mapped to Novation Peak in the following order: Noise, Filter Cutoff, Osc1 lvl, Osc2 lvl, Osc3 lvl, attack, sustain and decay.


had a blooming few moments today with nested affordances recorded onto tape and moved around in twine. @andrew thanks for these, they’re a real joy:)


lil update for this guy !

  • new significant features
    • value can be a function (!)
    • param binder method
  • breaking changes:
    • lib subfolder has been renamed (for submoduleing purposes), use include ‘lib/nest/core’ rather than include ‘lib/nest_/core’
    • change all range properties to min & max properties
    • change edge to text flag rather than integer
  • various minor additions & bugfixes
    • _txt.*.step
    • _enc.number.inc (non-integer use)
    • _txt.*.formatter

it’s a small thing, but i’ve found that value functions, i.e.:

foo = 10

n = nest_ {
    foo_controller = _grid.number {
        x = { 1, 16 }, 
        y = 1,
        value = function() return foo end,
        action = function(s, v) foo = v end
} :connect { g = grid.connect() }

are a game-changer when it comes to using nest_ in a complete script (like the new wrms), because you’re no longer limited to using nest as the sole data structure, so your “true” values can live in the params system & elsewhere.

I’ve iterated on study 4 to use this feature & wrote a bit more about it there !


yo! As a former tt gridops user, nest_ is super neat!

Currently working on a Kria-esque interface (with some fun algebra stuffs for generative whatever). Unfortunately my code experience is limited to TT and a teeny bit of norns customization, so questions are stacking quickly. Big one right now is re paging. It seems like in study 2, this chunk says:

enabled = function(self)

       return (seq.tab.value == self.key)


“If tab value is equal to the key for this affordance, enable this affordance”

But tab’s value is just 1 or 2 (the two buttons in the upper left). How / where is the key designated for this affordance though?

Apologies if this is answered in the studies – I’ve only been through them once and it usually takes me >6 exposures to this type of material to get it get it


the word “key” is definitely misleading out of context - for numbered tables, self.key is the index of a nest/affordance within its parent nest. here’s a link to the bit that attempts to explain pagination, if you want another go-around https://github.com/andr-ew/nest_/blob/master/study/study2.md#enabling

key could also could be a string, which is why we call it key instead of index - but yea, no relationship to light up buttons : )

in the case of the sequencer study, self.key is either 1 or 2, since there are two nests inside the seq.pages nest. thusly, seq.tab has a range of 1 - 2 which is set by the x property.

I can totally relate ! been learning the new web design frameworks this year & I think it took me 3-4 reads to actually be able to write any code : )

nest takes quite a bit less code & if statements to write an interface compared to the conventional way but there are some decently heady meta-concepts to wrap your head around. it definitely needs some steeping time before getting useful.

keep the questions coming !!! exciting to see others tackling this crazy thing. might encourage me to actually finish up the docs


tysm! This is as I expected but I think in my deployment there were syntax errors making weird values happen.

– I’ll give it another go in the morning and report back with findings.

1 Like

yea, lua loves doing this to ya. feel free to share code if u get stuck !

1 Like

Have made Great Progress. everything going on in my code makes sense to me, but it’s a few shades shy of what I’m looking for. have some Qs:

Is there an equivalent of enable that just… mutes interacting with an affordance while still leaving its lights up?

What’s the best way to change the brightness within an affordance based on variables in another affordance? Like the Kria gate page behavior, where gates outside the range of the current sequence are dimmer than gates within the range?

How do I control which affordance appears ‘on top’? As in the gates example: when I change a range, it conceals the gates within the range.

If you wouldn’t mind taking a peak at the general structure of this, I’d really appreciate it. Refactoring now is preferable to doing so once I’ve duplicated these structures (with slight variations) over 200 times >.> <.< >.>

yep! if you want to disable it permanently, just set input = false. if you want to enable it conditionally with a function, _affordance.input is an object with its own enable property - it’s a been a real hot second since I’ve tested this use case but I think a snippet like this would work (there might be bugs, i should test it!):

_grid.number {
    -- (replace grid.number.input with a customized version of itself)
    input = _grid.number.input {
        enabled = function() return stuff == true end

another alternative would be the decoupled input/output approach discussed here (using two different affordances for in & out and binding their values if desired).

great question ! for some things I imagine you could get away with layering another output-only affordance below the interactive affordance (addressing the layering question next) - in other cases you could send a function to level.

the level function is supposed to receive an x & y argument which map back to the position of the rendered key within in the affordance, but I think support might be spotty ? something like this is * supposed* to work:

_grid.number {
    x = { 8, 16 }, 7 = 1,
    -- brightness level of active key is higher between keys  3 - 6 within the affordance
    level = function(s, x, y)
        return (x >= 3 and x <= 6) and 15 or 4

the z property exists for exactly this ! any z > 0 is supposed to be rendered on top.

but: it recently started acting buggy. something about z not being set unless you go back and set z manually after initialing the nest (or something). It’s getting in my way for the project I’m working on now, so I think as soon as I get back to working on norns projects I’ll go ahead & fix this !

z is a pretty crucial feature in my mind, the ability to overlap affordances opens up quite a lot of possibilities (for example, using fingers to filter overlapping affordances by the number of simultaneous keypresses (I’m doing this, it’s neat))

will peek !!!

haha this makes me v curious what you are cooking up !

without having looked thru the code yet, I’m curious if you might be able to build a function or two to code your code 200 times ; )

It’s an interface for a Very Large array of quantizers (5 x 5 x 5 x 12 x 12 x 19 x 4). The interface side is really just Kria but with some fun algebraic nonsense + a page of mappable sliders

Thanks for the quick response. Should be plenty of leads for tomorrow’s sesh!

just pushed a very minor update, mostly bugfixes :rainbow:


  • ADD nest_:bind() generic binder method
    • like the param binder, but binds to any table with a get & set method
  • ADD grid/arc redraw is a global function (grid_redraw, arc_redraw). call these any time you need to force a redraw
  • FIX _affordance.output.handler
  • FIX *.binary value function gets overwritten
  • FIX _grid.number, _grid.control min & max
  • FIX _grid value function bugs
  • FIX z sorts in correct order
    • p.s., here’s some example usage for the z property, which controls draw order / layering when affordances overlap

Hey @andrew – really enjoying the studies. This is such a helpful tool to get going with the grid quickly.

I am facing a weird little difficulty with Study 2. Here is the code I am running:

Everything looks like it’s working as intended in maiden: the x and y coordinates are correct for each of them. However, the grid is lighting up in an unexpected fashion.

I get the correct background lights: a 5 x 5 square. However, the first light that is lighted up (level 15) is not (1, 1) as would be expected. Instead, it is (2, 2). Then, when I press elsewhere, the button I press is not lighted up. Instead, (x + 1, y + 1) lights up, where (x, y) is the button that I actually pressed. Here’s a quick video demonstrating:

If it is of any relevance, I am using a 2021 grid with a norns shield (up to date). I just installed nest yesterday so I believe I am up to date.

I am not entirely sure what is happening here, and any help would be greatly appreciated. Thanks again for this wonderful gift!!

1 Like

hey ! glad you’re digging into things.

that’s a known bug with the 2d version of number (apologies if I forgot to list in in the issues section) - are you planning to use this code for a project ?

1 Like