Your code stays the same. The assets move to CDN.

Make asset migration easier. Move your public/ assets to your desired storage provider, with supported asset references rewritten automatically during production builds—without manually updating your source code.

Next.js · Vite · React Native with Expo (experimental)

Before migrationYour assets are served from your application’s public/ directory.

In any state, source code never changes. Unchanged
<img src="/window.svg" alt="Window" />
simpcn — zsh
~/my-projectIllustrative demo
npx simpcn plan
Local  1 added
Proposed transfer 385 B

  upload     window.svg
Remote unchecked · run simpcn plan --check-remote
Dry run · no changes made.
Example assumes Simpcn is installed and configured. CDN URL is illustrative.

It starts with a single command.

Add Simpcn as a dev dependency.

simpcn — install
npm i -D simpcn

Moving assets is easy.
Updating every reference isn’t.

Moving files is one task. Keeping every reference in sync is another.

Repeated source edits
Header.tsx
<img src="/images/hero.webp" />
Find. Replace. Repeat.
Landing.tsx
<img src="/images/hero.webp" />
Find. Replace. Repeat.
Same source. Different delivery.
Landing.tsx Unchanged
<img src="/images/hero.webp" />
Production outputSupported reference → CDN URL
Supported references change at build time; source stays unchanged.

The manual route

Upload assets, then find and replace references across the source.

With Simpcn

Migrate assets. The production build rewrites supported references.

Automatic rewriting has a defined scope. See which references are supported

One reference. Two environments.

Same component. New destination.

Switch environments. The source stays the same.

Component✓ Unchanged
<img src="/images/hero.webp" alt="Product preview" />
Production asset URLhttps://cdn.example.com/assets/images/hero.webp
Verified assets resolve to the configured CDN URL.

Delivered from the configured CDN URL

Example configuration and requirements
simpcn.config.ts · delivery URL
publicBaseUrl: 'https://cdn.example.com/assets/'

The storage prefix is assets; the URL includes it once. Production requires a deployment record verified against the current asset bytes. The CDN domain shown here is illustrative.

Supported references and limitations

Plan it. Move it.
Keep writing code.

Preview first. Migrate next. Transform at build time.

01 · DiscoverSHA-256 fingerprint
02 · MigrateUpload + verify
03 · TransformProduction build
Production builds use verified delivery records.
  1. Discover

    Scan and fingerprint assets before uploading.

    npx simpcn plan
  2. Migrate

    Upload what’s needed and verify remote metadata.

    npx simpcn migrate
  3. Transform

    Rewrite supported references using verified deployment records.

    npm run build

A different delivery path.
The same everyday workflow.

Fewer manual edits
Supported references change at build time.
Local stays local
Development keeps local asset paths.
Incremental migration
Matching remote objects are verified and skipped.
Storage ownership
Use configured S3-compatible storage and delivery URLs.
Framework integration
Next.js and Vite adapters fit the existing build.

Native images.
Same source.

React Native with Expo, now in experimental support. Keep your image references while Simpcn prepares verified CDN sources for iOS, Android, and different screen densities.

Static imports and require()
Keep importing an image or passing a literal require() to Image, ImageBackground, or expo-image. Supported production references move to the CDN.
iOS and Android artwork
Use .ios and .android files behind one image reference. Each platform gets its own family, with a generic fallback when needed.
Sharp at @2x and @3x
Provide the density variants. Simpcn chooses a CDN image for the device’s pixel ratio and preserves its logical display dimensions.
Your component · unchanged
import { Image } from 'react-native';
import logo from './assets/cdn/logo.png';

<Image source={logo} />;
Your images · platform + density
logo.ios.png          // 24 × 24 pixels
logo@2x.ios.png       // 48 × 48 pixels
logo.android.png      // 24 × 24 pixels
logo@3x.android.png   // 72 × 72 pixels

The Expo adapter is experimental. Android/iOS exports are tested; device, EAS, and OTA validation remain. Essential and excluded images stay local.

Explore React Native with Expo

Fits right into
the existing build.

Keep the framework. Add Simpcn to the configuration.

16.4 · webpack + Turbopack

Static media references and verified static next/image sources are supported. Next.js CSS references stay local.

Read the Next.js guide

Already installed? Initialize the project, then update the framework config.

npm · initialize
npx simpcn init --framework next
next.config.ts
import { withSimpcn } from '@simpcn/next';

const nextConfig = {
  // Keep existing Next.js settings here.
};

export default withSimpcn(nextConfig);

Init creates the storage configuration and can install the adapter. Framework configuration stays explicit.

The storage stays under control.

Connect an existing bucket and its public delivery URL. Credentials stay outside the client bundle.

Configure storage

Then preview, migrate, build.

Upload and verify assets before the production build. Source files stay in place.

Follow the setup guide Set up Next.js
Requires Node.js 24.11+Available on npm

A few things to know.

Scope, storage, and the details that matter.

Supported references and limitations, explained.
Does Simpcn work with React Native?

The experimental Expo adapter handles static PNG/JPEG sources, iOS/Android variants, and @2x/@3x density files. Packed installation and platform exports are tested; device, EAS, and OTA validation remain. It does not cover Expo web or bare React Native. Explore the Expo integration.

Does Simpcn edit source files?

The migration and supported reference transforms do not rewrite application source files. Original public/ files stay in place. The framework integration changes supported references in production build output. Check the reference support guide.

Does every asset reference work automatically?

No. Static supported references can be transformed; arbitrary JavaScript strings, API responses, and dynamic paths are not automatically rewritten. Known dynamic asset paths can use the integration’s assetUrl() helper. Next.js CSS rewriting and Vue/Svelte template transforms are not implemented. Read the limitations.

Which storage providers are supported?

The S3-compatible adapter has configuration for AWS S3, Cloudflare R2, and MinIO. Live integration tests currently cover local MinIO; AWS S3 and R2 have not been live-validated. The bucket, public access, and any CDN must already be configured. Simpcn does not provision them. See storage setup.

What happens when assets change or are removed?

The next plan reports new, changed, unchanged, and locally removed assets. Migration verifies remote metadata and skips matching objects. Differing or unverified objects need --overwrite to replace them. Removed local files are reported; remote objects are kept. Review CDN caching after replacements. Explore the CLI.

Do production builds upload assets?

No. Run migration before the application build. Builds read local deployment records and fail when a managed reference lacks matching verification. Those records describe a previous storage check, not a guarantee that a CDN URL is currently public or cached correctly. Read the setup guide.

Can Simpcn replace an image optimization service?

Simpcn migrates assets and changes delivery URLs. It does not resize or optimize images. Supported static next/image references use direct CDN delivery with unoptimized; conflicting loader or optimization settings are left unchanged with a diagnostic. Review the integration limits.

Open source · v0.1

Build with it.
Help shape what’s next.

Try it. Share a rough edge. Contribute a fix.

Every contribution starts with an idea.