Back to projects
Logo Studio logo

Logo Studio

Tool for transforming and exporting vector logos, automating the generation of multi-platform assets.

SVG IndexedDB Satori

Managing and preparing visual identity for web environments requires multiple iterations: from adapting vector logos to generating manifests for Progressive Web Apps (PWAs), icons of different resolutions, and social cards (OpenGraph). The fundamental problem lies in the friction introduced by traditional graphic design tools, which are disconnected from the web development environment, and online tools that require server-side processing, exposing assets to network latency and privacy issues.

The solution I implemented consists of a tool that completely shifts the processing load to the client’s browser (client-side). This allows ingesting scalable vector graphics (SVG), analyzing them structurally to extract metadata (dimensions, color palettes), and applying geometric and chromatic transformations in real time before packaging the generated artifacts into multiple formats.

Main Operational Flow

  1. Ingestion and Normalization: The user uploads an SVG file. The system analyzes it using a DOMParser, extracting intrinsic dimensions (viewBox) and structuring a tree of color properties.
  2. Real-Time Transformation: The canvas workspace allows applying dynamic scales, translations, and chromatic replacements.
  3. Contextual Preview: Configuration metadata (border radii, backgrounds, theme colors) are injected into React components that simulate native environments (Web, Mobile, OpenGraph, PWA Manifest).
  4. Packaging and Export: Through programmatic rasterization on <canvas> elements, the modified vectors are converted to PNG or rewritten as modified SVGs. JSON configurations (manifest.json, app.json) are dynamically generated and consolidated into an asynchronous compressed file for download.

Software Architecture

The application follows principles of separation of concerns, operating as a monorepo that splits static routing, reactive state management, and local persistence. I opted for a hybrid Local-First architecture.

Structural Model

I decoupled the structural page loading, handled by a static routing engine (Astro), from the high-fidelity interaction flows, which rely on reactive components (React). This minimizes main thread blocking and accelerates the Time-to-Interactive metric.

graph TD
    Client["Client / Browser"] --> AstroRouter["Astro: Router and Static Shell"]
    AstroRouter --> ReactApp["React: Reactive Complexity"]

    subgraph Client-Side Rendering
        ReactApp --> EditorState["State & Event Management"]
        ReactApp --> GeneratorLibs["Generator Libraries: SVG, PWA, OG"]
    end

    subgraph Local Persistence
        EditorState <--> DexieDB["(IndexedDB / Dexie.js)"]
        DexieDB --> SyncEngine["Live Queries"]
    end

    GeneratorLibs --> CanvasAPI["Canvas Rasterization"]
    CanvasAPI --> Export["Zip / PNG Generation"]

State and Event Management

The interactive core is managed through React with state derived from active persistence (Live Queries). User actions (drag & drop, color inputs) emit events that directly mutate the local database. The interface component is subscribed to these changes, ensuring that the Source of Truth is always the data layer and not the ephemeral in-memory state of React.

Data Modeling (IndexedDB)

Persistence is managed through Dexie.js, providing an asynchronous schema over IndexedDB. The main model, Project, is an aggregate entity that consolidates both raw assets (SVG) and output configuration parameters.

erDiagram
    Project {
        number id PK
        string name
        string svgContent "Original/normalized vector payload"
        object colors "Color recoloring key-value map"
        number borderRadius
        string backgroundColor
        number logoScale
        number logoX
        number logoY
        string displayMode "PWA: standalone, fullscreen, etc."
        string themeColor "PWA Manifest"
        string appBackgroundColor "PWA Manifest"
        array selectedSizes "Export dimensions"
        array selectedExtraAssets "Additional assets: favicon, og, manifest"
        date createdAt
        date updatedAt
    }

This flattened and denormalized structure is optimized for atomic reads and writes of a single document per work session, which is ideal for a document-oriented architecture in the browser.

4. Technology Stack

Tool decisions respond to criteria of maximum client-side efficiency and compatibility with modern web standards.

Layer / DomainTechnologyTechnical Justification
Framework ShellAstro (v5.2.5)Fast initial rendering, SEO, file-based routing management, native i18n ([lang]) support.
Interactive LayerReact (v19)Complex interface management (UI Editor), canvas life cycles, drag-and-drop components.
Local PersistenceDexie.js (v4.3)IndexedDB wrapper. Allows asynchronous and reactive queries (useLiveQuery) without blocking the UI.
Styles & CSSTailwind CSS (v4)Design systems using pure utility classes, facilitating local variables and native dark mode support.
SVG/PNG ManipulationCanvas API & JSZipClient-side transformation from vectors to bitmaps. Consolidation of exports in memory.
OpenGraph GenerationSatoriJSX-to-SVG engine to build meta-social images, configured to use local WOFF2 fonts.
Linting & FormattingBiome.jsUnified static analysis tool, replacing ESLint and Prettier with exponential execution time improvements.
TestingVitest / PlaywrightUnit tests for utilities and end-to-end tests for user interaction flows.

Conclusion

The implementation of this system demonstrates that shifting the entire graphical processing workflow to the client mitigates reliance on dedicated backend infrastructures, eliminating data transfer costs, cloud persistence, and manipulation latency. The use of IndexedDB ensures structural resilience between sessions, and the hybrid composition of Astro and React guarantees optimal static delivery without sacrificing client-side state sophistication.