Build Lucidchart

KINDAreplaces $9/mosaves $108/yrback to the verdict

0%0 of 20 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A browser editor with shape libraries whose shapes carry defined connection points, layers you can lock and hide, connectors that stay attached through moves and resizes, and diagrams generated from a spreadsheet so an organisation chart or a network map is regenerated rather than redrawn.

estimated effort multi-daythe files for this build are in the project pack

RuntimeTypeScript with Vite, rendering SVGShapesA library format defining geometry and connection points as dataLayoutelkjs for generated diagramsData bindingCSV or JSON to shapes through a mapping you defineStorageIndexedDB with file open and save

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the build.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installfree

    Why Phase 5's export check is meaningless if the only thing you open the file in is the browser that made it.

    Get it Inkscape is free and strict, which makes it a good test. open ↗

    Verify You can open an SVG and see whether its fonts survived

  3. have readyfree with open licences

    Why Export embeds or outlines fonts, which is redistribution and not permitted by every licence.

    Get it Use openly licensed families and keep the licence files.

    Verify Each bundled font's licence permits embedding, or export outlines text

  4. have readyfree

    Why Phase 4 is only meaningful against real data, and real organisation data has the awkward cases: someone with two managers, a vacant role, a name that is very long.

    Get it Use a real team structure or a network inventory. Thirty rows is enough to see layout problems.

    Verify The spreadsheet loads and includes at least one awkward case

  5. decidefree

    Why A general diagram tool needs hundreds of shapes; a specific one needs a dozen. Deciding which diagrams you make keeps the library finite.

    Get it Pick the diagram type you draw most and list the shapes it needs. That list is your first library.

    Verify The list exists and is under about twenty shapes

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- docs(id, title, updated_at), pages(id, doc_id, name, ordinal)
- layers(id, page_id, name, ordinal, visible, locked)
- shapes(id, page_id, layer_id, library_key, x, y, w, h, rotation, text, style_json, data_key)
- connectors(id, page_id, layer_id, from_shape, from_port, to_shape, to_port, label, style_json, waypoints_json)
- libraries(id, name, shapes_json) · geometry and named ports per shape, as data rather than code
- bindings(id, page_id, source_kind, source_ref, mapping_json, last_generated_at) · what regenerates a data-linked diagram
- A connector stores shape and port names. Storing coordinates is what makes edges detach the first time something moves.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
VITE_LIBRARY_DIRrequired/librariesWhere shape library files are served from. Adding a shape is a file here.
VITE_FONT_DIRrequired/fontsSelf-hosted fonts with their licence files beside them.
VITE_LAYOUT_DIRECTIONrequiredDOWNDefault direction for generated hierarchies.
VITE_SHARE_ENDPOINToptionalhttps://share.example.comProduct phase only. Leave unset to keep everything local.

The build, in order

  1. Shape libraries as data

    A shape is a definition anyone can add to, not code you have to change.

    1. Geometry, named ports with relative positions, default style. Written down before implementation.

      Files docs/library-format.md

    2. One renderer reading the data. No shape-specific code paths.

      Files src/shapes.ts

    3. So two libraries can define a shape with the same name.

      Files src/libraries.ts

    done when · tick each as it passes
    watch out
    • Hard coding shapes as drawing functions means every new shape is a code change and a release, which is why diagram tools with rich libraries build them as data. Define the format first, including how a port's position is expressed relative to the shape's size, so a resized shape keeps its ports in the right places.
  2. Connectors that survive editing

    Moving or resizing a shape keeps its connectors attached and sensibly routed.

    1. The relationship is the data. Geometry is derived at render time.

      Files src/connectors.ts

    2. Perpendicular exit, minimal turns, avoiding the connected shapes' bodies.

      Files src/route.ts

    3. Deleting a shape removes its connectors. Test for orphans explicitly.

      Files src/doc.ts

    done when · tick each as it passes
    watch out
    • Storing a connector as two points works until the first move, and then every diagram anyone saved is subtly wrong. Store the relationship and derive the geometry, which also makes automatic layout possible later.
  3. Layers

    A complex diagram can be worked on one layer at a time.

    1. Ordered, affecting render order as well as interaction.

      Files src/layers.ts

    2. Hidden and locked layers are excluded before anything is selected, not after.

      Files src/select.ts

    3. The connector references shapes, so this should be free; test it anyway.

      Files src/layers.ts

    done when · tick each as it passes
    watch out
    • Letting selection reach a locked layer defeats the point of locking, and it is the most common way a background diagram gets dragged out of place. Filter selection by layer state at the hit test rather than checking after the fact.
  4. Diagrams generated from data

    An organisation chart regenerates from a spreadsheet instead of being redrawn.

    1. Columns to text, style and parent relationships, defined once as a mapping.

      Files src/bind.ts

    2. So regeneration is an update rather than a rebuild, which is what preserves manual work.

      Files src/bind.ts

    3. Layered layout for hierarchies, with an overlap assertion after.

      Files src/layout.ts

      terminal
      npm install elkjs
    done when · tick each as it passes
    watch out
    • Regenerating from scratch discards every manual adjustment, and a diagram nobody can tweak is one people rebuild by hand elsewhere. Key generated shapes to their data rows, so a regeneration updates existing shapes rather than replacing them, and manual overrides survive.
  5. Export that opens elsewhere

    An exported diagram is usable in other tools, not just yours.

    1. Embedded or outlined, viewBox set to content bounds.

      Files src/export-svg.ts

    2. Never upscale a bitmap. Compare against an upscaled version to confirm.

      Files src/export-png.ts

    3. Inkscape or a design tool. The browser that made the file is not a test.

    done when · tick each as it passes
    watch out
    • An exported SVG referencing a web font renders in a fallback face on any machine that lacks it, which is every machine but yours. Embed the font as data or outline the text, and verify by opening the file in a different application rather than in the browser that made it.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more diagrams.