THE FIELD GUIDE

Start here

Your first form, from blank canvas to working app.

Run dotnet run --project src/Forma.Builder from the repository root. Close the old Builder before rebuilding its executable. The native Windows host contains the web workspace: menus, toolbox, canvas, inspector and docked code editor.

Start with a project

Builder opens on a full-window start screen. Choose New project, Open project, a recent project, or a Login form, Settings dialog, or Dashboard template. Templates provide a starting layout; sign-in, storage, and dashboard data still need your application logic. Save a new design to keep it.

Recent entries show their last saved time. Removing an entry only removes it from the recent list; it does not delete the project file. Missing files are marked. Choose Go to the designer or press Escape to close the start screen. Use File → Start page to return later. Startup actions become available after the host finishes loading, without briefly exposing the designer first.

Build and test a small form

  1. Click Toolbox in the left sidebar, then drag a Panel onto the form, then drop a TextBox, Label and Button inside it. The children belong to the panel and move with it. Double-clicking a toolbox entry also inserts a control.

  2. Name them nameInput, greetingLabel and greetButton in Properties. Names are unique identifiers; the read-only ID stays stable across renames.

  3. Move and resize them using selection handles or Layout values. Change zoom and confirm movement still uses form coordinates. Hold Alt to bypass snapping guides; Escape cancels an active drag.

  4. Select the Button and click Custom Properties… below the property search. In the Script tab, replace the starter source with:

    forma.on("click", () => {
      const name = String(forma.get("nameInput", "value") ?? "").trim();
      forma.set("greetingLabel", "text", name ? `Hello, ${name}!` : "Enter a name.");
    });
  5. Save the editor, then click Preview. Type a name and click the button. Preview runs a separate design copy in a resizable window with maximize support. Close it to end that runtime session. Saving script edits requires a fresh Preview to test the changed source.

  6. Save the project with Ctrl+S. Open the .forma file with Ctrl+O to confirm the design and script reopen. Ctrl+Z/Ctrl+Y undo and redo design edits; focused text editors keep their own text undo behavior.

Edit faster

ActionHow
Find a command, control, or formCtrl+K opens the command palette
Show the keyboard shortcut sheetF1 or Help → Keyboard shortcuts
Select several controlsCtrl/Shift+click, or drag a rectangle on the form
Select all controlsCtrl+A while the design surface has focus
Copy / cut / paste / duplicateCtrl+C / Ctrl+X / Ctrl+V / Ctrl+D
Move the selectionArrow keys; Shift uses 10-pixel steps
Resize the main selected controlAlt+Shift+arrow; Ctrl uses 10-pixel steps
Zoom the canvasCtrl+wheel, Ctrl+=, or Ctrl+-; Ctrl+0 restores 100%
Open a control's default event handlerDouble-click a placed control

Alignment/distribution actions operate on the eligible selected controls. Selecting a panel and its child does not move or copy the child twice. Pasted controls receive fresh IDs/names. Locked controls and managed layouts still restrict editing. Focused inputs and the code editor keep their own shortcuts.

The toolbar's Fit zoom accounts for the form frame and available canvas space. The selection breadcrumb lets you select a parent container directly. Form-size presets resize the form rather than changing canvas zoom. View options include a snapping grid and tab-order overlay; hold Alt during dragging to bypass snapping. The workspace offers keyboard navigation and labelled controls.

Browse the project

The left sidebar switches between Explorer and Toolbox. Solution Explorer shows all forms, nested components, source files, the global script and image assets in use. Click a component to select it in Design, or expand it and click script.js, event.js, component.css or custom-properties.json to edit that source. See Solution Explorer for search and keyboard navigation.

Add another form

Choose File → New form or Ctrl+N. The new form belongs to the current project; use the form selector above the canvas to return to the first form. Save retains all forms in the same file. Use File → New project or Ctrl+Shift+N to start a separate project. Preview runs the currently selected form.

From Preview, forma.showForm("settingsForm", { modal: true }) opens another form from the same project and returns a promise for its close result. See project files and multi-form Preview.

Layout and properties

Panel and GroupBox allow free positioning. Flow/stack/table layouts own child positions; X/Y edits do not override their arrangement. Use layout slots for split panes, tabs and table cells. TabControl has an Add tab action and horizontal or vertical tabs. Dock/Anchor apply to free-position children; Dock controls position and can control dimensions. This is intentional layout behavior.

Click empty form space to edit the form title, dimensions and appearance. Use property search to find component-specific settings. Enabled/Visible affect Preview; Design keeps components selectable. Locked prevents design edits. The workspace theme toggle changes the editor, not your form's appearance.

For live values outside events, use forma.bind and read .value when needed. For shared values, open Project → Main script and use forma.provide/forma.use or forma.shared. See the script guide, runtime property reference and global script examples.

Preview runs inside Builder. A saved design is not an exported executable; executable export and generated C# event handlers remain roadmap work.

Architecture and contributing

BuilderViewModel owns design state; services validate editing, persistence, properties and Preview operations. Views host native windows and dispatch browser messages. The browser handles immediate pointer feedback, while C# validates committed edits. Preview owns its own model and reactive script scope. See the MVVM architecture and folder structure.

Before adding a control, check the roadmap and toolbox implementation. A complete addition needs a model, renderer, factory/toolbox registration, contextual inspector properties, persistence, supported script operations and meaningful verification.

Automated checks

dotnet build Forma.slnx
dotnet test Forma.slnx
node --test tests/WebRuntime/*.test.cjs

Desktop testing complements these checks for pointer interactions, rendering and native window integration.

Search components, properties, and guides.

↑↓ navigate Enter open Esc close