Upgrading

This page covers breaking changes between PicFast versions and how to migrate. Each section is self-contained — only read the one matching your current version.

From 0.15.x to 0.16

v0.16 collapses the theme system to a single built-in theme. Six presets, the token palette, JSON theme package import/export, and the per-user theme_override were all removed.

What you lose

  • Admin site settings: the standalone "Visual style" page is gone; the page was merged into the new "Site info" page and exposes only a custom_css field. The "Theme package" import/export UI is removed.
  • User settings: the "Appearance" tab under personal settings is gone. The only theme-related control users have is the light/dark/system switcher in the header (kept as basic usability, not as personalization).
  • Stored data: every old value still sits in the site_settings.theme_config JSONB blob and in users.settings.theme_override for users who set one, but the application no longer reads any of it.

What you keep

  • All your existing site_settings.theme_config.custom_css is preserved and now drives the site's <style> tag on its own.
  • Your existing per-user image_processing, default_strategy, default_album, default_permission settings are unaffected.
  • Database schema is unchanged. No data migration is required to start the new image — values become dead weight, not errors.

Step 1: Deploy the new image

The standard upgrade path applies. Migration 029 runs at startup and cleans up users.settings.theme_override on every row. The old site_settings.theme_config is left untouched — the application now ignores all fields except mode and custom_css.

docker compose pull
docker compose up -d

Step 2: Recreate any preset you were using

If you had picked one of the six removed presets (default / moe / cyber / pixel / terminal / fresh), or customized the token palette or public surface fields, the visual baseline is gone. Paste the matching custom_css below into Admin → Site info → Custom CSS to restore the closest equivalent.

default

No custom_css needed.

moe (pink soft glow)

:root {
  --primary: oklch(0.70 0.16 350);
  --accent: oklch(0.92 0.05 350);
  --background: oklch(0.99 0.01 350);
  --ring: oklch(0.70 0.16 350);
}
.pf-site-logo { border-radius: 1.25rem; }

cyber (neon dark)

:root {
  --background: oklch(0.13 0.02 280);
  --foreground: oklch(0.95 0.02 280);
  --card: oklch(0.18 0.03 280);
  --primary: oklch(0.78 0.20 200);
  --accent: oklch(0.72 0.25 320);
  --border: oklch(0.28 0.04 280);
  --ring: oklch(0.78 0.20 200);
}

pixel (hard edges, retro)

:root {
  --radius: 0.125rem;
  --border: oklch(0.85 0 0);
}

terminal (green-on-dark)

:root {
  --background: oklch(0.05 0 0);
  --foreground: oklch(0.85 0.18 145);
  --card: oklch(0.08 0 0);
  --primary: oklch(0.75 0.22 145);
  --border: oklch(0.20 0.05 145);
  --ring: oklch(0.75 0.22 145);
}

fresh (mint accent)

:root {
  --primary: oklch(0.72 0.10 195);
  --accent: oklch(0.94 0.04 195);
  --background: oklch(0.99 0.005 195);
  --ring: oklch(0.72 0.10 195);
}
.pf-site-logo { border-radius: 0.875rem; }

Step 3: Recreate any token overrides

If you had overridden primary, accent, or radius in the old token panel, copy the value(s) into a :root block in your custom_css:

:root {
  --primary: oklch(0.65 0.20 30);
  --radius: 0.875rem;
}

Step 4: Recreate any public-surface fields

If you had set background_image

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: url('https://your-host/bg.jpg');
  background-size: cover;
  background-position: center;
}
.pf-public-glow { display: none; }

If you had set logo_shape

/* circle */   .pf-site-logo { border-radius: 9999px; }
/* square */   .pf-site-logo { border-radius: 0; }
/* rounded */  .pf-site-logo { border-radius: 0.75rem; }

Step 5: Tell users about mode

The light/dark/system switcher now stores the choice in the browser's localStorage rather than the user's server profile. Cross-device sync is gone. Each user picks their mode once per device.

Rollback

If v0.16 doesn't fit:

  1. Roll back to the v0.15 image. No database change is required — the old JSONB fields still hold the previous configuration.
  2. Open Admin → Site info (in v0.15) → Visual style, copy the current theme_config as a JSON dump for reference.
  3. Re-upgrade to v0.16 and re-apply via custom_css using the recipes above.

FAQ

I never set any theme options. Am I affected?

No. Your site_settings.theme_config is {} or {"custom_css": "..."}; the upgrade is a no-op for you.

One of my users had picked a preset. What do they see?

The user is back on the default theme. Their theme_override has been wiped by migration 029. Ask them to pick a mode in the header (dark gives a closer feel to cyber or terminal if you intend to keep either of those for the rest of the site).

Can I export my old theme before upgrading?

Yes. On v0.15 open Admin → Site info → Visual style → Theme package → Copy JSON. Save the dump locally. After upgrading to v0.16 the import button is gone; translate the preset / tokens / public fields by hand using the recipes above.

Can I get the presets back?

The preset picker is not coming back. Use the custom_css recipes above to recreate any of the six looks; the result is identical because the underlying tokens were the only thing varying.

My custom_css is hitting the 20,000-character limit. What now?

That's a hard limit (was implicit before, now enforced). Try:

  • Hoist repeated values into CSS variables, reference them by name elsewhere.
  • Drop vendor prefixes — Tailwind already handles compatibility.
  • Move stable shared rules to index.css in a fork and ship your own image.