EdgeStore

Hono

Learn how to integrate EdgeStore with your Hono backend and React frontend.

Some applications are built with React on the frontend (e.g. using create-react-app or vite) and have a hono backend.

You can use EdgeStore in these cases, even without using Next.js.

Setup

Install

Install @edgestore/server in the backend and @edgestore/react in the frontend. In a workspace, run the package installation in the corresponding package directories.

npm install @edgestore/server @edgestore/react

Environment Variables

Then go to your Dashboard, create a new project and copy the keys to your environment variables.

.env.local (backend only)
EDGE_STORE_ACCESS_KEY=your-access-key
EDGE_STORE_SECRET_KEY=your-secret-key

Reuse the backend's existing environment-file convention and loader. The maintained Hono example loads .env.local in its development command; add that file to .gitignore. Never put these keys in frontend VITE_* variables.
You don't want to commit your secret keys to your repository.

Backend

Now we can create the backend code in our Hono app.

The example below is the simplest bucket you can create with EdgeStore. Just a simple file bucket with no validation that will be accessible by anyone with the link.

You can have multiple buckets in your app, each with its own configuration.

import { createEdgeStore, initEdgeStore } from '@edgestore/server';
import { createEdgeStoreHonoHandler } from '@edgestore/server/adapters/hono';
import { edgestore } from '@edgestore/server/providers/edgestore';
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import { cors } from 'hono/cors';

// --- HONO CONFIG ---

const PORT = process.env.PORT ?? 3001;
const frontendOrigin = process.env.FRONTEND_ORIGIN ?? 'http://localhost:5173';
const app = new Hono();

/**
 * Your Hono app is probably running in a different port than your frontend app.
 * To avoid CORS issues, we should use the cors middleware.
 */
app.use(
  '/edgestore/*',
  cors({
    origin: frontendOrigin,
    credentials: true,
  }),
);

// --- EDGESTORE ROUTER CONFIG ---

const es = initEdgeStore.create();

const router = es.router({
  publicFiles: es.fileBucket(),
});

export type EdgeStoreRouter = typeof router;

const configuredEdgeStore = createEdgeStore({
  router,
  provider: edgestore(),
});

const handler = createEdgeStoreHonoHandler({
  edgestore: configuredEdgeStore,
});

// --- HONO ROUTES ---

app.get('/', (c) => {
  return c.text('Hello from Hono server!');
});

// Route for EdgeStore
app.all('/edgestore/*', handler);

// Start the server
serve(
  {
    fetch: app.fetch,
    port: Number(PORT),
  },
  (info) => {
    console.log(`⚡Server is running here 👉 http://localhost:${info.port}`);
  },
);

Frontend

Now let's initiate our context provider in the frontend app.

src/lib/edgestore.ts
// Use a type-only import from your actual Hono backend, not another adapter's example.
import { type EdgeStoreRouter } from '../../../path/to/hono-backend/src';
import { createEdgeStoreProvider } from '@edgestore/react';

const { EdgeStoreProvider, useEdgeStore } =
  createEdgeStoreProvider<EdgeStoreRouter>();

export { EdgeStoreProvider, useEdgeStore };

And then wrap our app with the provider.

src/App.tsx
import { EdgeStoreProvider } from '../lib/edgestore';

function App() {
  return (
    <EdgeStoreProvider basePath={import.meta.env.VITE_EDGESTORE_BASE_PATH ?? '/edgestore'}>
      {/* Rest of your app */}
    </EdgeStoreProvider>
  );
}

For Vite development with separate origins, set VITE_EDGESTORE_BASE_PATH=http://localhost:3001/edgestore in the frontend environment and FRONTEND_ORIGIN=http://localhost:5173 in the backend environment. Use your actual ports. The base path is public configuration, not a credential. Across separate repositories, publish or otherwise share the backend router's types without importing backend runtime code into the browser bundle.

Usage

To upload or use the other functionalities of EdgeStore, you can look at the main Quick Start guide. The usage should be the same.

Limitations

For EdgeStore to work properly in your deployed production app, Your frontend and backend should be in the same domain.

If you are deploying to Vercel, you can take a look at the Rewrites settings. In case you are using Apache or Nginx, you can set up a reverse proxy to make sure your frontend and backend are in the same domain.

On this page