Atomic Elements
An element is a single-language backend, Drift's unit of a “service” (what you'd put in one container elsewhere), minus the container. One language, one dependency manifest (go.mod / requirements.txt / package.json / …), and as many @atomic functions as you like across flat files in one folder.
The common case is the simplest there is: drop your handlers straight into atomic/ as flat files and the CLI auto-discovers every @atomic function, with no per-function folders and no list to maintain. That flat set is an element (the implicit default one):
-
atomic/one element, one language, one backend
- auth.gopost:signup · post:login · get:me
- groups.gocreate · list · join · get
- lib.goshared helpers, just a sibling file
- go.modone manifest for the whole backend
Need a second language? That's a second element, a second service. Give each its own folder under atomic/ (say atomic/api/ in Go and atomic/ml/ in Python), each with its own manifest. Mixing languages within one element is refused at discovery; a second language is, by definition, a second element. Elements integrate through Backbone (queues, NoSQL, locks), exactly the way microservices integrate through a broker, never by importing each other.
An element is an authoring + dependency boundary, not a URL one: routes always come from each function's @atomic directive, so the element name never appears in the path. Shared code (lib.go, crypto.go) is an ordinary file in the same package and never a copy. Go, Python, Node, Ruby and PHP build as multi-function elements; a Rust element holds one function. (Folder-per-function deploys too, if you prefer it: that's an element with one function.)