Getting StartedThree commands, no Node, no bundlers, no JavaScript:
dotnet new install eQuantic.UI.Templates
dotnet new equantic-app -n MyApp
Open the printed URL: a themed, server-rendered page whose counter is a C# component: a state field, a handler, and a Build method. The build compiled it to JavaScript for you (the embedded toolchain does the bundling; there is nothing to install).
What the template gives you
├─ MyApp.csproj # <Project Sdk="eQuantic.UI.Sdk">, that line IS the build pipeline
├─ global.json # pins the SDK version (stamped by the template)
├─ Program.cs # AddUI → UseTheme → MapUI, UseRequestLocalization for the cultures
│ └─ StatTile.cs # your first component; its factory is generated from it
│ └─ HomePage.cs # [Page("/")], a write-once StatefulComponent
├─ Strings.resx # your strings: ordinary .NET resx, the only localization artifact
•
Pages are classes with [Page("/route")]. SSR, hydration, client-side navigation, a true 404 for unknown routes (declare [Page("/404")] to brand it), all wired.
•
Two languages from birth. The home page reads Strings.Tagline from the resx and renders a CultureSwitcher: click Português and the page re-renders in place, Contado {0} vezes. reformatting with the counter. Ship a third language by adding Strings.fr.resx and listing fr in UseRequestLocalization. See Localization for how the same class answers on the server, in the browser and in a native window. •
Writing a tree needs no new and no import: `Column(gap: Space.S4, children: [ Text("Hi"), Button("Go") ]). Your own components join that surface automatically, and StatTile(…)` in the template is yours. See Declarative Surface. •
Theming is one line: swap PhotonTheme.Instance for MaterialTheme.FromSeed(color) in Program.cs and every component rebrands, server and client.
•
Server data goes through [ServerAction] methods, called from the browser as ordinary C# awaits.
•
Hot reload: run with dotnet watch and save a file, and the browser updates with your page state replayed.
•
The same component source realizes NATIVELY on the Photon engine (macOS/iOS/Android shells). See Photon. Starting from a shape instead of a blank page
Since 0.2.0-preview.31
The layout above is --shell blank, the default. Both templates take the parameter, and every shape it offers is ADAPTIVE — which is the point: a form factor is not a second project here, so the first screen a newcomer sees had better say so.
dotnet new equantic-app -n MyApp --shell dashboard
dotnet new equantic-native -n MyApp --shell tabs
blank
One page and a counter.
topnav
A header with links, and a second route to prove the router.
dashboard
A sidebar past 840dp, the same sections wrapped under the header below it.
equantic-native
What you get
blank
One screen and a counter.
tabs
Destinations in a bottom bar, standing up as a navigation rail past 600dp.
drawer
A sliding panel on a phone, docked beside the content past 840dp.
list-detail
One pane at a time on a phone, two side by side on a tablet.
A template per form factor would deny the write-once thesis on the first file a developer opens, so this is a dotnet new CHOICE on the two templates instead. The shape lives in ONE file — AppShell — and nothing else names it: on native, Program.cs says UseRoot<AppShell>() whichever you picked; on the web a shell is an ordinary component every page composes, so it has a generated factory like any other and a page writes AppShell("/", …). Swapping the shape later is one file, never the entry point.
The adaptive halves carry no listener and no second state: AdaptiveNode holds both trees, the web emits both behind build-time media queries (the right one is on screen at first paint, before any JavaScript runs) and Photon lays out the one that fits the window. See Write-once components. Until packages are on nuget.org, point a nuget.config at the feed that carries them:
<add key="equantic" value="PATH-OR-URL-TO-FEED" />