Imports
Imports let you split your Newt code across multiple files and reuse components, themes, and variables.
Syntax
Use the import keyword followed by a string path:
import "theme.newt";
import "components.newt";
Import statements go at the top of the file, before any other declarations.
Relative paths
Paths are resolved relative to the importing file. Given this file structure:
project/
app.newt
components/
cards.newt
buttons.newt
themes/
dark.newt
You would import like this:
// app.newt
import "components/cards.newt";
import "components/buttons.newt";
import "themes/dark.newt";
What gets imported
When you import a file, all of its top-level definitions become available in the importing file:
- Components -- any
componentdeclarations - Themes -- any
themedeclarations (you still needuse themeto activate one) - Variables -- any
letdeclarations
Example: importing components
// components.newt
component Avatar(initials) {
box(fill: #e0e7ff, radius: 999, width: 40, height: 40)(
center()(
text { content: initials, fontSize: 14, fontWeight: "700" }
)
)
}
component UserRow(name, role) {
row(gap: 12, align: "center", padding: 8)(
Avatar("GS")
column(gap: 2)(
text { content: name, fontSize: 14, fontWeight: "600" }
text { content: role, fontSize: 12 }
)
)
}
// app.newt
import "components.newt";
screen Main {
column(gap: 8, padding: 24)(
UserRow("Ganesh", "Developer")
UserRow("Alex", "Designer")
)
}
Example: importing a theme
// theme.newt
theme Brand {
let primary = #7c3aed;
let bg = #f9fafb;
let text_color = #111827;
let border = #e5e7eb;
}
// app.newt
import "theme.newt";
use theme Brand;
screen Main {
column(fill: bg, padding: 32)(
text("Styled with imports", fill: primary, fontSize: 20)
)
}
Importing the theme file makes the Brand theme available, but you still need use theme Brand to activate it and expose its variables.
Example: importing variables
// config.newt
let maxWidth = 960;
let defaultPadding = 24;
let defaultRadius = 8;
// app.newt
import "config.newt";
screen Main {
container(padding: defaultPadding)(
card(radius: defaultRadius, fill: #ffffff, stroke: #e5e7eb, padding: 16)(
text("Config imported", fontSize: 16)
)
)
}
Circular import detection
The compiler detects circular imports and reports an error. If a.newt imports b.newt and b.newt imports a.newt, the compiler will refuse to compile and show a clear error message indicating the cycle.
To resolve circular imports, extract the shared definitions into a third file that both can import:
// Before (circular):
// a.newt imports b.newt
// b.newt imports a.newt
// After (resolved):
// shared.newt has the common definitions
// a.newt imports shared.newt
// b.newt imports shared.newt
Transitive imports
Imports are not transitive. If a.newt imports b.newt, and b.newt imports c.newt, the definitions from c.newt are not automatically available in a.newt. You need to import c.newt explicitly if you want to use its definitions.
// If you need definitions from both files:
import "b.newt";
import "c.newt";
Best practices
- Keep one theme per file for easy swapping.
- Group related components into a single file (e.g.,
cards.newt,navigation.newt). - Use a
config.newtfor shared constants like spacing, colors, and sizing values. - Place import statements at the very top of the file for readability.
Next steps
- Themes — define shared themes and import them across files.
- Components — import reusable components from other files.
- CLI Reference — compile multi-file projects with the CLI.