Skip to content
Docs for Flare v2.0.0Archived release · 08064f6bBuild details ↗Versions & changes
View docs

customization-roadmap

Original documentation published with v2.0.0 on 2026-09-13. This release predates the handbook. Commands and external services reflect that release.

This roadmap treats appearance, upload workflows and integrations as equal priorities. The first implementation delivers the appearance studio, upload profiles and portable recipes, and scoped tokens with signed file-ready webhooks. The broader opportunities below remain future work; this release does not provide an arbitrary plugin runtime, multiple storage targets, collections, or the full proposed policy system.

Flare should let someone create a recognizable home for their files: their brand, their sharing experience, their workflows, and their integrations. The strongest opportunity is to make those choices reusable and consistent across the web app, screenshot tools, public links, and APIs.

This is a product and implementation proposal, based on source inspection at commit b135a85 and primary documentation reviewed on September 13, 2026. It does not implement the features below. Code observations have not been reproduced in a running application. The requested priority is equal weight for personal customization, powerful workflows, and a community ecosystem. Each milestone therefore needs a useful outcome in all three tracks; technical dependencies determine sequencing within a track, not its importance.

Three kinds of ownership should work together:

  • Instance ownership: an operator controls branding, available features, infrastructure, and enforced policies.
  • Personal ownership: each user controls their workspace, upload defaults, and public presentation within those policies.
  • Community ownership: people can exchange themes and recipes, then build integrations and extensions without maintaining a Flare fork.

The product test is concrete: a person creates “Orbit,” imports a light/dark theme, chooses a minimal screenshot page, and saves a 24-hour screenshot profile. Uploading through ShareX or dragging into the dashboard produces the same result. They export the design/profile as a reusable pack and connect a service that receives a file-ready event through documented APIs. Another user chooses a personal theme without changing Orbit’s public brand.

The existing code provides a useful starting point.

AreaWhat exists todayOpportunity and relevant code
AppearanceInstance color presets and token editing, favicon, custom CSS/head HTML, footer-credit toggleFirst-class branding, separate light/dark palettes, portable themes, and user preferences. See config, theme editor, and head customization.
Public sharingFile viewers, uploader details, generated social metadata, private/password-protected filesConfigurable page layouts, disclosure controls, and embed templates. Most presentation is fixed in the public file page.
Personal workflowVanity path, filename randomization, default expiry/action, generated screenshot-client configurationsNamed upload profiles, copy formats, saved views, and cross-device preferences. See user schema, profile UI, and filter hook.
UploadsMultipart streaming, chunk uploads, browser paste, visibility/password/expiry controlsA common server-side policy resolver and finalization service. See multipart route, chunk initialization, and paste form.
OperationsGlobal quota/upload limits, registration/OIDC/email configuration, local or S3 storagePer-user policy overrides, reproducible configuration, multiple named storage destinations, and explicit content origins. See storage interface and email config.
ExtensibilityInternal database events, expiry handlers, OCR, modular viewer componentsDurable public events, webhooks, processing actions, and versioned viewer/provider contracts. See events, OCR, and viewer dispatch.

These are foundations, not existing plugin support. The user schema currently has two roles and no general preferences, collections, per-file storage identity, or named upload-profile models. Quota enforcement inspected in the upload routes uses an instance default for non-admin users; individual quota policy would be new. next-themes is present, but a persisted user-facing theme chooser would also be new.

Other projects help establish expectations. Zipline documents JSON themes with light/dark choices, per-upload naming, expiry, compression, folder and domain options, and upload/shorten webhooks. Chibisafe documents albums, tags, and companion capture tools in its project README. The proposed differentiator for Flare is the integration of these ideas: accessible visual editing, portable presets, consistent upload behavior, and understandable extension contracts. This research is not a comprehensive competitive ranking.

The opportunity map covers all three equally important tracks:

CapabilityWhat someone could make their ownInitial scope and later expansion
Brand and appearance studioInstance name, tagline, light/dark logos, favicon, colors, typography, radius, density, background, shadows and motionStart with curated font/background choices and semantic tokens. Add locally hosted assets, scoped advanced CSS, and a portable theme library. Apply branding to login, navigation, share pages, metadata, footer and email identity.
Share-page designsMinimal image page, framed screenshot, branded file delivery, or code/paste page; visible uploader/date/filename/statistics; image fit; action placementStart with three component-based presets and structured options. Later add approved content blocks, public collection pages, optional landing pages, and per-user/per-file presentation overrides.
Upload profiles“Public screenshots,” “Private work,” “Temporary clip,” “Code snippet”Combine visibility, expiry/action, naming and returned link format first. Extend with share design, collection, domain, OCR, metadata stripping, transforms and destination as those features ship.
Personal dashboardGrid/list view, card density, displayed metadata, default sort/page size, saved searches, pinned navigation, default landing pagePersist preferences by account. Add keyboard shortcuts, locale/time zone, thumbnail behavior and viewer preferences. Preserve browser/system accessibility choices.
Collections and organizationProject asset libraries, screenshot journals, client delivery galleries and saved searchesStart with tags, manual collections and smart collections defined by filters. Add covers, descriptions, ordering, branded public views and optional intake links. Public collection membership must never implicitly publish a private file.
Links and social previewsApproved domains, slug formats, original/random/date/word-based naming, extensionless aliases, Markdown/HTML/direct-download copy formatsCentralize URL generation first. Add validated title/description placeholders, social-card presets and per-profile choices. Clients ultimately control embed rendering, so preview cannot promise identical presentation on every platform.
Processing and automationStrip metadata, resize/compress, apply a watermark, choose OCR language, auto-tag, notify another service, or expire contentStart with signed webhooks and a few built-in actions. Add a declarative “when / if / do” editor with dry-run results and execution history. CPU-intensive OCR/transforms should be optional workers.
Screenshot-specific presetsPresentation padding, backgrounds, frames, shadows and captions; optional crop/annotation/redaction before uploadStart with share-page framing that preserves the original. Later add client-side editing with an explicit original-versus-edited preview; redaction must remove pixels from the uploaded result, and retaining an original must be a separate choice. Expose treatments as reusable profile options.
Operator controlFeature availability, file-type restrictions, quotas, upload/retention limits, storage destinations, notification policy and user exceptionsSeparate defaults from enforced constraints. Add import/export, environment/file management, change history and impact previews. Role/group policies can follow actual multi-user demand.
Extension ecosystemNew metadata extractors, viewers, automation actions, capture clients and storage providersDeliver data-only theme/profile packs, external integrations and developer documentation in the first milestone. Expand the SDK after first-party implementations exercise each new contract. Add discovery and update management after install, upgrade, disable and removal work reliably.

Three example workflows make the opportunity easier to judge. A personal screenshot host could use random readable URLs, an image-first page, an automatic Markdown copy format, and optional EXIF stripping. A work account could default to private files, a 24-hour expiry, and a compact dashboard. A designer could collect public assets under a branded gallery, publish a chosen share-card style, and notify a configured service when a file is ready. These are proposed compositions; processing, collections, automation, and multiple domains are later capabilities.

The settings experience needs to stay manageable as this grows. Operators should see categories such as Identity, Appearance, Sharing, Uploads, Storage, Access, Email, and Integrations, with search across settings. Users should see Personalize, Upload profiles, Sharing defaults, and Connected tools. Common choices get clear controls and useful presets; advanced controls remain available nearby. Avoid adding another long tab to the existing roughly 1,780-line settings page.

Each inheritable control should explain its current value: “From instance,” “From profile,” or “Managed by environment,” with a reset-to-inherited action. A user should be able to preview a theme or share design with image, video, PDF, paste, password-protected and unavailable-file examples before publishing. Include narrow-screen and light/dark previews. Publish related appearance changes atomically, keep the previous revision, and let operators recover the stock administrative UI if custom CSS breaks it.

The architecture can grow incrementally around the existing application. Proposed module and model names below are design suggestions, not files already in the repository.

  1. Establish a small typed configuration contract. Split the current schema into logical modules as each feature is implemented. Describe each new setting’s validation, default, allowed scope, exposure, override behavior and whether it applies immediately or requires restart. Use the same definitions for runtime validation, API views, environment mapping and documentation; complex editors still deserve purpose-built UI. Keep the existing Config storage initially, add a schema version and revision, and use section/path updates with optimistic conflict detection. The existing advisory lock already serializes writers, but whole stale snapshots can still overwrite newer values. A generic schema framework or replacement database is unnecessary for the first release.

  2. Separate saved values, effective values, and policy. Generalize the useful pattern already present in email config: validated environment and _FILE overrides, managedFields, server-owned state, encrypted secrets, redacted views, and preservation of saved fallbacks. For operator-owned fields, explicit environment/file management takes precedence over database settings; reject conflicting declarations. Environment variables must not blanket-override unrelated personal preferences. For inheritable upload defaults, resolve built-in → instance → user → selected profile → allowed request overrides, then validate against policy. A profile can select an allowed domain or reduce retention, but cannot exceed quotas or relax a required access restriction. Define per-field constraint composition rather than deep-merging policies. For example, permitted type sets intersect and maximum-size limits take the stricter value. Invalid explicit requests return a useful error instead of silently changing the requested privacy behavior.

  3. Give appearance and public presentation distinct scopes. A user's dashboard theme belongs to that user. A shared file's brand belongs to its owner or instance, while the viewer's accessibility needs remain respected. Resolve those independently. Add an optional versioned UserPreferences record when personal controls ship, with absent values meaning inheritance. Persist expiry/access decisions on upload; editing a profile affects future uploads. Version share designs and pin a selected revision on a file when stable presentation is wanted. Updating old files or republishing an old design should be an explicit bulk operation with an impact summary.

  4. Unify upload policy before adding profile complexity. Introduce shared resolveUploadOptions and finalizeUpload services used by multipart and both chunk-completion paths. Paste already posts to /api/files; it needs to submit the selected profile instead of maintaining independent defaults. Use explicit ingress context if profiles distinguish pastes; this path does not currently populate File.isPaste. Resolve naming/storage choices before streaming bytes, using a profile header or initialization request so multipart field order cannot alter routing. Persist the resolved profile revision and options in chunk-upload state. At completion, recheck current permissions and actual-size/quota constraints, then atomically create file metadata, account for storage and record required follow-up work. Reserve quota transactionally so concurrent uploads cannot all spend the same remaining capacity; reconcile abandoned object writes/reservations. Preserve streaming and define retry/idempotency behavior. Keep legacy client response shapes through adapters until a versioned API migration; do not silently break existing ShareX/scripts. Initially, passwords remain per-upload overrides and are excluded from reusable profiles and portable packs.

  5. Create stable appearance and pack contracts. Render the brand through shared components and derive metadata through one service. Use explicit token names for colors, typography, surfaces, radius, density and effects, with separate light/dark values. Packs should contain a versioned manifest, tokens, supported share-design/profile options and validated local assets; they should import into a draft and include no credentials or server code. Let people export selected customization without exporting users or files. Import previews must list changes and resolve destination-specific references such as domain, collection or backend IDs through explicit mapping; never assume another instance's IDs mean the same thing. Use documented component attributes/slots for advanced styling. Existing CSS is forcibly rewritten with !important in CustomHead and colors are separately injected by ThemeInitializer; preserve this as a legacy path while new themes use one predictable application path. Conversion must be previewable, not a silent rewrite of someone's existing design.

  6. Treat public URLs and storage locations as separate identities. Centralize canonical app, share and raw-content origins; today upload responses and public metadata derive their origins differently. Use an operator-approved domain registry, verify ownership before allowing user-added domains, and document reverse-proxy/TLS requirements. Keep authentication on the canonical app origin initially. Add aliases without rewriting existing links or storage keys. Before multiple destinations ship, add StorageBackend and a per-file backend reference; pin chunk sessions and derived assets to their backend as well. The current storage singleton selects one global provider, and File.path alone cannot identify where an old object lives. Backfill existing files against verified storage inventory. Switching the default should affect new uploads only; migration needs copy, integrity verification, resumability, and a separate decision to delete the old copy. Provider contracts should declare optional capabilities such as direct URLs and multipart operations. Audit every read/delete/export path, including account deletion, before claiming provider interchangeability.

  7. Make events durable before offering automation. Extend the database event system with transaction-aware emission, atomic claims, leases, bounded concurrency and per-action delivery state. The current worker accepts but does not enforce maxConcurrency, and the consumer uses a process-local processing set. The mail outbox provides a stronger local precedent for leases and FOR UPDATE SKIP LOCKED; reuse its approach without mixing general event payloads into the mail tables. Start with versioned file.created, file.ready, file.deleted, file.expired and url.created contracts as needed. Give each action idempotency keys, timeouts, bounded retry/backoff and inspectable failures. Do not claim exactly-once delivery to external services.

  8. Expose narrow extension points from the first milestone. A theme or recipe should work without executable code. Publish the pack schema, upload/profile API contract, webhook event schema and runnable example integration alongside their first release. External integrations should use scoped API tokens and signed webhooks. Later, trusted built-in adapters can implement versioned contracts for processors, viewers and storage providers. A manifest should declare identity, version, compatible API version, settings schema and requested capabilities. Third-party server processors should run in an operator-managed separate process/container with bounded resource and network access; a TypeScript interface is not isolation. Untrusted browser viewers need a separate origin/sandbox and narrowly scoped file access. A dynamic npm loader inside the main Next.js process should not be the initial extension mechanism.

The main data additions can therefore arrive when needed:

Delivery pointMinimal likely additionsWhy
Appearance and preferencesConfig schema/revision, appearance history or draft records, optional UserPreferencesAtomic publishing, rollback, personal overrides and portable themes
ProfilesUploadProfile with owner/revision/options; resolved upload metadataConsistent defaults and reproducible behavior across upload clients
Collections and domainsTags/collections with explicit membership and visibility; domain/alias recordsOrganization and presentation without conflating membership with permission
Multiple backends and transformsStorageBackend, file backend reference, durable upload sessions, FileVariantSafe reads/deletes after switching defaults, multipart recovery and protected derivatives
Automation and integrationsEvent leases and per-action delivery records; hashed scoped ApiToken recordsReliable retries and credentials that grant only the required operations

Authorization and delivery semantics belong in these contracts. Hiding a download button does not prevent copying bytes already delivered to the browser. Hiding an uploader must also remove it from public metadata and embeds if nondisclosure is intended. Private/password-protected files, thumbnails, transformed variants, OCR and extension endpoints must share access checks. A metadata-stripping profile must finish stripping before any public original URL is exposed. If a required processor fails, retain a pending/failed state with owner diagnostics; do not publish the unprocessed original. Optional notification failure should not invalidate a completed upload.

Keep existing administrator custom CSS/head customization available as an explicit trusted override. Do not automatically grant that capability to theme authors or ordinary users. Community packs should initially be data-only with validated asset types and no remote asset fetching by default. Public templates should use escaped, allowlisted variables and structured components. Admin API views, exports, logs and previews must exclude secrets; extend email's existing redaction/encryption approach to other credentials without changing deployed email secret derivation. Imports must show privacy/retention changes in a draft and must never silently publish or replace a user's defaults.

The initial external integration contract needs precise behavior:

  • file.ready means the file has completed required processing and its intended access state is committed; it does not mean the file is public. Record one logical transition transactionally, deliver at least once, and give retries the same event/idempotency ID. Default payloads exclude credentials, OCR/body content and private presigned URLs. Recheck subscription ownership/enablement and current disclosure policy before dispatch; suppress unauthorized payloads after deletion or privacy changes and record why.
  • Sign a versioned payload with its timestamp, document replay-window validation and secret rotation, and pin event identity/content across retries. Validate destination scheme, resolved IPs and redirects on every attempt. Private-network destinations require an explicit operator allowance. Bound queue size, concurrency, timeouts and token/account request rates.
  • Authentication must carry scopes and profile/account restrictions through every handler. In particular, new integration tokens must not inherit the ability to read/rotate the legacy credential through upload-token routes. Credential management requires an interactive account session. Support expiration, revocation and last-used visibility. Old installed uploader credentials need compatible verification; new token generation should use one-time reveal, with client configuration generated while that value is available.

Run three parallel tracks against shared milestones. Equal priority means each gets an owner, a working demonstration, and explicit acceptance criteria at every milestone. It does not require identical implementation effort or shipping an unrestricted plugin runtime immediately.

MilestoneCustomization trackWorkflow trackEcosystem track
Make it yoursBranding, light/dark themes, personal theme choice and three share-page presetsNamed upload profiles, consistent server defaults, copy formats and client exportsPortable theme/share/profile packs, documented API, scoped tokens, one signed file-ready webhook, delivery history and runnable integration example
Shape your daily useSaved dashboard views, viewer preferences and branded collectionsTags/collections, a few processing actions, simple automation rules and approved domain choicesPack recipe catalog, integration examples, additional event types and first-party adapters using documented contracts
Build beyond coreAdditional public-page blocks and viewer contributionsMultiple storage destinations, richer processing and resumable migrationsVersioned processor/viewer/storage SDKs, install/update/disable tooling and community discovery

Implement these as small, reviewable slices. The following IDs describe dependencies, not a requirement to finish the appearance track before starting the ecosystem track. Relative effort indicates scope uncertainty, not a calendar commitment; medium and large slices should be split into focused PRs.

SliceDeliverable and user-visible resultDependencies and main code touchpointsRelative effort
1Shared typed settings/revision contract exercised through branding; initial pack/API schema conventionsConfig, settings API, layouts, navigation, footer, email identityMedium
2Appearance studio with light/dark tokens, personal theme choice, draft/preview/publish, restore, and validated theme import/exportSlice 1; theme components, background, shared UI surfaces, user preferences; establish legacy CSS compatibilityMedium–large
3Common upload-option resolution and finalization; correct existing defaults and chunk option propagationCan proceed alongside appearance; upload routes, upload hook, expiry handler and client generatorsMedium–large
4Named profiles in web upload, drag/drop, paste and generated clients; consistent visibility, naming, expiry/action and copy formatSlice 3; profile storage and API; preserve legacy integrationsMedium
5Three share-page presets: Minimal, Framed, Delivery; metadata disclosure, image fit, title/description templates; profile selectionSlice 1; compatible with slice 2; public page, metadata, protected viewers and access helpersMedium
6First ecosystem release: share/profile pack portability, documented API, scoped tokens, one signed file-ready webhook, delivery history and example integrationStart alongside slices 2–4; slice 3 supplies transactional emission; implement leases, idempotency and access controls before webhook launchMedium–large
7Saved dashboard views, viewer preferences, basic tags/collections and approved domain aliasesAfter first milestone; membership/access models and central URL serviceMedium–large
8More event types, built-in processing/automation recipes, protected derivatives; named storage destinations as a separate workstreamSlice 6 delivery primitives; file/backend identity and inventory migration before storage routingLarge
9Expanded processor/viewer/storage SDK, two or more first-party examples per exposed contract, compatibility/disable/recovery toolingExtend the contracts delivered in slice 6 as slice 8 exercises themLarge

The first balanced milestone consists of slices 1–6. Appearance, profiles and the initial ecosystem can ship incrementally as their dependencies pass. Milestone completion requires a working outcome in each track. If the scope needs reducing, reduce depth across the tracks: curated theme controls, three page presets, existing profile options, and one event/integration contract. Collections, multiple backends, an automation canvas and a hosted marketplace can follow.

The first implementation batch should open three bounded workstreams: branding with the minimal settings revision contract; common upload-default/finalization behavior; and pack/API/event contract fixtures plus the first external integration example. The ecosystem work can build against those fixtures while upload emission is implemented. Preserve the current Flare identity and current integrations through migration. This ties architectural investment to something usable in every track.

Several code findings should become explicit acceptance work rather than being buried under new controls:

  • The expiry dropdown associates DAY with “One hour” and HOUR with “One day”; profile validation excludes DISABLED although the dropdown offers it. Verify and correct the round trip in the upload-consistency slice.
  • The main upload form derives the user's expiry in the browser, while global drag/drop supplies only maximum size. The multipart endpoint acts on explicit expiry. Test defaults at the server boundary so generated clients and paste cannot diverge.
  • Chunk initialization records public visibility and no password. Propagate and persist the resolved access settings through initialization and completion, including expiry action.
  • General config reads fall back to the entire default config on database/validation errors. Versioned migration must distinguish a missing optional field from unavailable or invalid policy. New policy resolution should fail with a diagnosable unavailable state instead of silently relaxing saved restrictions. Keep operator recovery available.

Migration should be additive. Populate branding from current defaults, preserve existing tokens/CSS/head and footer choices, and give new preference fields an inherited state. Turn existing user randomization/expiry choices into the initial effective profile without changing old files. Distinguish absent, explicitly disabled, empty, and reset values in every API. Back up the old config before schema conversion and reject unsupported future schema versions with an actionable message. Theme/profile imports must not modify infrastructure secrets, setup state, identities or access policy. A full operator configuration export is a separate artifact with secret references. Changing configuration must invalidate the appropriate caches across running instances; storage/profile decisions already attached to an upload must remain stable.

Completion should be demonstrated with the following scenarios, as features land:

ScenarioPass condition
Make the instance yours“Orbit” name/logos, selected theme and configured footer appear consistently on login, dashboard, share pages and metadata, with no code edits or rebuild.
Import and recoverExport a theme, import it into another instance's draft, publish and restore the prior revision. Invalid packs cannot affect the live UI; the operator can recover from broken legacy CSS.
Upload consistentlyThe same profile produces the same visibility, password behavior, retention/action and naming across browser upload, drag/drop, paste, multipart clients and chunk uploads. API overrides cannot bypass policy.
Keep personal choices personalTwo accounts can use different themes/layout preferences. Shared-file branding follows the configured owner/instance choice and still respects reduced motion and keyboard access.
Protect every representationPrivate/protected metadata, thumbnails, raw/direct/download routes and later variants/extensions all preserve the intended access and disclosure rules.
Upgrade without surprisesAn existing database/config and old screenshot-client configurations continue to work; old links resolve; default appearance is unchanged unless a user chooses a new design.
Build and share an integrationA second instance imports a theme/profile pack into draft, reviews mapped references and privacy/retention changes, publishes and restores. Unsupported versions leave live settings unchanged. A contributor runs the documented webhook/API example without patching Flare; scopes are enforced and secrets stay out of packs.
Recover asynchronous workFrom the first webhook release, process restart and retries do not lose required deliveries or duplicate committed effects. A failing webhook cannot block unrelated uploads.
Change storage safelyWhen multiple destinations ship, old files still preview/download/delete from their recorded backend after changing the default; interrupted migrations resume safely.

Validation should combine configuration migration/precedence/concurrent-save tests, upload contract tests across ingress paths, and integration tests for private/expired files and background work. Before the first webhook release, cover a crash after commit but before dispatch, duplicate delivery, receiver outage/429/timeout, disabled endpoints, revoked tokens, cross-account/profile denial and private-file disclosure. Preserve existing scheduled-expiry payloads during event migration and make deletion/quota effects idempotent. Use visual review of login, dashboard, share and protected states for the new appearance surfaces, including mobile, light/dark and legacy custom CSS. Measure upload memory/latency and worker throughput before and after pipeline changes on representative local and S3 storage. Establish performance budgets from those baselines rather than inventing targets without measurements.

Product success can be checked without adding mandatory telemetry: in usability sessions, can someone complete the Orbit scenario, explain where an inherited value came from, recover an unwanted theme change, and reuse a profile without editing a script? Track time and confusion points in those sessions. Later, judge the extension contracts by whether an independent contributor can add an integration using documented APIs without patching core files.

The first design decisions to settle during implementation are the preset styles and token vocabulary, which public-presentation controls ordinary users may override, the initial profile fields, and the first public event/API/pack contracts. Default to three curated page presets, personal theme choice, operator-controlled public-brand overrides, profiles containing controls Flare already largely supports, and one well-documented file-ready integration. Every milestone should make Flare more personal, more useful in daily workflows, and easier for someone else to extend.