> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ploterr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create a Vite app, describe a room as data, show it in 3D, and move a door with one command.

In this quickstart you write a small building as a document: four walls, a door, a window and a floor. Floorkit builds the 3D model from it. Then you move the door with one command.

Use a modern browser and a Node.js version supported by [Vite](https://vite.dev/guide/): 20.19+ or 22.12+. If you have a Vite TypeScript app already, skip the first step.

<Steps>
  <Step title="Create the project">
    Create a plain TypeScript app. No UI framework is required.

    ```bash theme={null}
    npm create vite@latest floorkit-app -- --template vanilla-ts --no-interactive
    cd floorkit-app
    ```

    Follow [Installation](/floorkit/installation) in this folder to install Floorkit and its peer packages. The template supplies the `dev` and `build` scripts used below.
  </Step>

  <Step title="Create the page">
    Put this in `index.html`:

    ```html theme={null}
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Floorkit quickstart</title>
        <style>
          html,
          body,
          #app {
            margin: 0;
            width: 100%;
            height: 100%;
          }
          canvas {
            display: block;
          }
        </style>
      </head>
      <body>
        <div id="app"></div>
        <script type="module" src="/src/main.ts"></script>
      </body>
    </html>
    ```
  </Step>

  <Step title="Describe the building">
    Put this in `src/main.ts`. The document has one building with one storey. Positions are `[x, z]` in metres.

    ```typescript theme={null}
    import * as THREE from 'three';
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
    import { BuildingSession, Floorkit, type BuildingModel } from '@opengeometry/floorkit';
    import wasmURL from 'opengeometry/opengeometry_bg.wasm?url';

    const model: BuildingModel = {
      schema: 'floorkit.building-model',
      version: 3,
      units: 'meters',
      upAxis: 'y',
      id: 'my-first-building',
      buildings: [
        {
          id: 'building',
          storeys: [
            {
              id: 'ground',
              elevation: 0,
              height: 3,
              walls: [
                {
                  id: 'outer-walls',
                  points: [
                    [0, 0],
                    [6, 0],
                    [6, 4],
                    [0, 4],
                  ],
                  closed: true,
                  thickness: 0.2,
                  openings: [
                    { id: 'front-door', kind: 'door', offset: 1.5, width: 0.9, height: 2.1 },
                    {
                      id: 'front-window',
                      kind: 'window',
                      offset: 4.2,
                      width: 1.2,
                      height: 1.2,
                      sillHeight: 0.9,
                    },
                  ],
                },
              ],
              slabs: [
                {
                  id: 'ground-floor',
                  profile: {
                    outerRing: [
                      [-0.1, -0.1],
                      [6.1, -0.1],
                      [6.1, 4.1],
                      [-0.1, 4.1],
                    ],
                  },
                  thickness: 0.2,
                  baseOffset: -0.2,
                },
              ],
            },
          ],
        },
      ],
    };
    ```

    The wall path is the centre line of the walls. The floor outline is 0.1 metres outside that path, so the floor ends at the outer face of the 0.2 metre walls.
  </Step>

  <Step title="Build it and show it">
    Add this below the document. A `BuildingSession` builds the geometry. Its `root` is a Three.js group that you add to your scene.

    ```typescript theme={null}
    async function main(): Promise<void> {
      const container = document.getElementById('app');
      if (!container) throw new Error('The #app element is missing.');
      await new Floorkit().setupOpenGeometry(wasmURL);

      const scene = new THREE.Scene();
      scene.background = new THREE.Color(0xf3f4f6);
      scene.add(new THREE.AmbientLight(0xffffff, 1));
      const sun = new THREE.DirectionalLight(0xffffff, 2);
      sun.position.set(4, 8, 6);
      scene.add(sun);

      const camera = new THREE.PerspectiveCamera(50, 1, 0.1, 100);
      camera.position.set(9, 6, 9);
      const renderer = new THREE.WebGLRenderer({ antialias: true });
      container.appendChild(renderer.domElement);
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.target.set(3, 1.2, 2);

      const session = new BuildingSession(model);
      scene.add(session.root);

      const resize = (): void => {
        const width = Math.max(1, container.clientWidth);
        const height = Math.max(1, container.clientHeight);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.setSize(width, height);
        camera.aspect = width / height;
        camera.updateProjectionMatrix();
      };
      new ResizeObserver(resize).observe(container);
      resize();

      renderer.setAnimationLoop(() => {
        controls.update();
        renderer.render(scene, camera);
      });
    }

    main().catch((error: unknown) => console.error(error));
    ```
  </Step>

  <Step title="Run the app">
    ```bash theme={null}
    npm run dev
    ```

    Open the localhost address that Vite prints. You see a room with a door and a window. Drag to turn the view and scroll to zoom.

    Run `npm run build` to check the TypeScript and produce your app. A deployed hostname needs a valid [license key](/floorkit/licensing).
  </Step>

  <Step title="Make your first edit">
    An edit is a command. This command moves the door one metre along its wall. Floorkit cuts the wall again and keeps the edit for undo.

    ```typescript theme={null}
    function moveDoor(session: BuildingSession): void {
      session.apply(
        {
          kind: 'move-hosted-opening',
          buildingId: 'building',
          storeyId: 'ground',
          wallId: 'outer-walls',
          openingId: 'front-door',
          offset: 2.5,
        },
        session.revision,
      );
    }
    ```

    Call `moveDoor(session)` in `main`, after `scene.add(session.root)`.
  </Step>
</Steps>

## What you did

* You wrote the building as a typed document. The door and the window are entries in their wall, and the wall has real openings for them.
* You gave the document to a `BuildingSession`. It checked the document and built the geometry.
* You changed the building with a command. You did not move a mesh.

## Next steps

For generated building JSON, continue with the [agent building workflow](/floorkit/agents/agent-building-workflow). For a saved project with views, sheets, and editors, use [ProjectManager](/floorkit/api/editor/project-manager).

<CardGroup cols={2}>
  <Card title="How Floorkit works" icon="layer-group" href="/floorkit/concepts/architecture">
    Learn the parts that you used.
  </Card>

  <Card title="Draw a wall" icon="grip-lines" href="/floorkit/guides/draw-a-wall">
    Start the modelling guides.
  </Card>

  <Card title="Create a plan view" icon="compass-drafting" href="/floorkit/guides/create-a-plan-view">
    Make a drawing from this room.
  </Card>

  <Card title="Export a PDF" icon="file-pdf" href="/floorkit/guides/export-a-pdf">
    Put the drawing on a sheet and export it.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.