All projects
productFeatured

CONTENTFUL MANAGER — Cross‑Platform Desktop App + Marketing Site

Personal
Jul 2026 Jan 1970 (Ongoing )
Team of 1

Product Owner

01 Problem

  • Everyday Contentful operations — exporting/backing up content, importing between environments, adding locales, generating spreadsheets — require the Contentful CLI, a Node.js install, and hand‑written scripts, which is a steep barrier for content and marketing teams.
  • Advanced "release" tasks are the hardest and most error‑prone: after promoting an environment, custom app / UI‑extension IDs referenced in editor interfaces no longer match the destination, and translation entries have to be copied and re‑published by hand.
  • That release automation historically lived inside project‑specific AWS AppSync/VTL resolvers — hardcoded to one organization, space, token, and set of environments — so it couldn't be reused generically or safely.
  • Management API tokens are routinely mishandled (plaintext `.env` files, tokens committed to git, tokens pasted into browser tools).
  • There was no polished, installable, cross‑platform GUI that wraps these operations with dry‑run previews, guardrails, progress, and history.
  • Finally, the tool needed a fast, SEO‑friendly website to present the features and distribute signed macOS/Windows builds.

02 Solution

  • Built Contentful Manager, a generic, offline‑capable Electron desktop app that works with any Contentful organization, space, and environment using only a Management API (CMA) token — paired with a TanStack Start marketing site for distribution.
  • Bundled the official Contentful CLI inside the app and spawn it via Electron‑as‑Node, so end users install nothing (no Node.js, no CLI).
  • Shipped the core content operations as guided workflows:
    • Export All — bulk‑export every content type to dated JSON (a dependable backup)
    • Import All — import a folder of JSON with pre‑flight validation and per‑file selection
    • Add Locale — create locales with optional fallbacks
    • Generate Excel — convert an export into a multi‑sheet workbook (one sheet per locale)
    • Designed an extensible Release Operations module for promoting content and configuration between environments:
      • Custom App Mapping
        • Perform Mapping — after a merge/release, remap a destination environment's editor interfaces from the source's custom‑app IDs to the destination's, with a dry‑run preview, a per‑field diff, optimistic‑concurrency writes, and a confirm‑then‑apply flow
        • Add / Update Mappings_ — an editable mapping table with auto‑detect of installed apps and UI extensions, drag‑and‑drop between cells, search/validation, lock/edit mode, and JSON import/export
      • Environment Mapping Configuration — choose which environments participate in mapping
      • Translation Migration — copy translation entries that exist in one environment but not another, with a searchable, sortable diff preview (key, value, content type, destination status), selective row migration, and one‑click publish
  • Refactored the legacy, project‑specific AppSync/VTL resolvers into generic, reusable TypeScript services — parameterized by org/space/environment, using a single CMA token for read+write, preserving all locales, and using proper API‑returned versions instead of fragile revision arithmetic.
  • Engineered production‑grade safety: dry‑run previews, native confirmation dialogs, `409` conflict retry, `429` rate‑limit backoff, partial‑failure reporting, and "retry failed".
  • Secured secrets end‑to‑end: the CMA token is encrypted by the OS keychain (Electron `safeStorage`), lives only in the main process, and never reaches the renderer or the network.
  • Built a compiler‑enforced IPC contract and a hardened Electron runtime (context isolation, sandbox, no Node integration, Electron Fuses, strict CSP).
  • Added local persistence and history: settings, operation history, and release configuration are stored as JSON in the OS user‑data directory, with live logs, progress bars, and a "save log" export.
  • Made the whole app fully generic and re‑brandable (bundle identity, About panel, metadata, copyright), removing all project‑specific assumptions.
  • Built a marketing landing site (TanStack Start SSR) with a hero, feature grid, Release Operations showcase, how‑it‑works, macOS/Windows download flow with first‑launch guidance, roadmap, and FAQ — optimized for SEO and deployed to the edge.

03 Key Responsibilities

  • 01Architected an npm‑workspaces monorepo: a framework‑agnostic, unit‑tested core, a shared IPC contract, and the Electron shell.
  • 02Designed and implemented the Release Operations framework (registry‑driven, additive) so new migration operations plug in without touching existing code.
  • 03Ported project‑specific AppSync/VTL automation into generic services for editor‑interface app‑ID sync and translation migration, with dry‑run/apply semantics.
  • 04Built the Contentful Management API client (REST over `fetch`) with pagination and centralized rate‑limit backoff, plus editor‑interface, entry, content‑type, app‑installation and extension helpers.
  • 05Implemented **secure token storage** (`safeStorage`), local JSON persistence, operation history, and a streaming job system (live logs + progress + cancel) over Electron IPC.
  • 06Managed global UI state with Zustand and server/query state with TanStack React Query; built reusable, accessible UI (editable data tables, drag‑and‑drop, dialogs, toasts).
  • 07Bundled and spawned the official Contentful CLI via Electron‑as‑Node, and solved npm‑workspaces hoisting so the CLI closure ships inside `app.asar.unpacked`.
  • 08Configured Electron Forge packaging, Electron Fuses hardening, icons, and macOS/Windows code signing + notarization; pinned the toolchain to Node 20 LTS for reliable builds.
  • 09Wrote Vitest unit tests for the core services and kept the codebase clean with ESLint + Prettier and strict TypeScript across all workspaces.
  • 10Designed and built the marketing website (TanStack Start + Tailwind v4 + shadcn/ui), including SEO (JSON‑LD, OG/Twitter meta, sitemap), theme switching, scroll‑reveal animations, and the download experience; deployed live using vercel and Cloudflare.

Impact

  • Turned CLI‑only, script‑driven Contentful workflows into a one‑click desktop experience usable by non‑developers — no Node.js, no CLI, no scripts.
  • Made previously risky environment promotions safe and repeatable: every write is preceded by a dry‑run preview and a diff, with conflict/rate‑limit handling and partial‑failure recovery.
  • Generalized organization‑specific release automation into a reusable, org‑agnostic framework, eliminating hardcoded spaces, tokens, and environment names.
  • Hardened the security posture** — OS‑encrypted tokens that never leave the machine, a locked‑down Electron runtime, and content that flows only between the user and Contentful.
  • Delivered cross‑platform, signed installers for macOS and Windows from a single codebase, distributed through a fast, SEO‑optimized landing site.
  • Demonstrated end‑to‑end product engineering:
    • Desktop application architecture (Electron main/preload/renderer, compiler‑enforced IPC)
    • Framework‑agnostic, testable service design and legacy‑to‑generic refactoring
    • Complex client state (Zustand) + server state (TanStack React Query)
    • Secure secret handling, packaging, code signing & notarization
    • SSR marketing site with strong SEO and edge deployment

04 Technology Stack

Frontend

ReactTypeScriptZustandTanStack React QueryTailwind CSSRadix / shadcn‑style UIViteElectron

Backend

Contentful Management API (REST)Electron `safeStorage` (OS keychain — encrypted token)

Infrastructure

VercelCloudflareGitHub Releases

Architecture Notes

  • Structured a three‑package monorepo:
    1. core (framework‑agnostic Contentful logic, unit‑tested),
    2. shared (IPC channel names + request/response types),
    3. desktop (Electron + Forge + Vite + React).
  • Enforced a compiler‑checked IPC contract end‑to‑end: a single source of channel names and DTOs shared by main, preload, and renderer, so drift is a type error.
  • Applied a strict security model: context isolation on, sandbox on, Node integration off, a preload allowlist of IPC channels, Electron Fuses, and a locked‑down Content Security Policy.
  • Kept business logic transport‑agnostic via `onLog` / `onProgress` / `AbortSignal` callbacks, wired to Electron IPC by the host — the same seam that streams live logs and progress to the UI.
  • Implemented a registry‑driven operation model (operations and release operations) so features are additive — a new operation is data plus a form, with no changes to existing code.
  • Ported the legacy per‑environment app‑ID matrix into a user‑configured mapping table persisted as JSON (`org → space`), with import of the legacy matrix format and export for sharing.
  • Made release writes safe by default: dry‑run preview → review/diff → confirm → apply, with `X‑Contentful‑Version` optimistic concurrency, `409` re‑read‑and‑retry, and centralized `429` backoff.
  • Solved packaged‑CLI bundling (npm‑workspaces hoisting) by re‑installing the exact runtime‑dependency closure into the packaged app and unpacking it from the asar archive.
  • Pinned the project to Node 20 LTS to keep the Electron 33 build toolchain deterministic across install and packaging.
  • Built the website as an SSR, edge‑deployed app with self‑contained feature sections, scroll‑reveal animation, light/dark theming, and structured SEO metadata for discoverability.
  • Designed for future extensibility — additional release/migration operations (assets, entries, roles, webhooks, tags, workflows) reuse the shared environment‑pair selector, data‑table, job pipeline, and preview→apply workflow.

Links

Interested in working together?

Let's discuss how I can help with your next project.

Get in touch