@thefinder/core
v0.6.0
Published
theFinder server engine: a framework-agnostic file manager backend with local disk and S3 storage, chunked uploads, zip, trash and version history. Zero dependencies.
Maintainers
Readme
Install
npm i @thefinder/coreQuick start
import { createTheFinder, createFileServer } from "@thefinder/core";
import { localDriver } from "@thefinder/core/local";
const driver = localDriver({ root: "./uploads" });
const finder = createTheFinder({
volumes: [{ id: "files", name: "Files", driver, url: "/uploads" }],
});
// Bun, Deno, Hono, Next.js route handlers, Cloudflare Workers…
Bun.serve({
routes: {
"/api/files": finder.handler,
"/uploads/*": createFileServer({ driver, prefix: "/uploads" }),
},
});On Express, Fastify, Koa or plain node:http, wrap the handler with an adapter:
import { toExpress } from "@thefinder/core/node";
app.all("/api/files", toExpress(finder.handler));Then point the UI at it: @thefinder/react.
Entry points
| Import | What |
|---|---|
| @thefinder/core | createTheFinder, createFileServer, serveFile, zip stream, errors, types |
| @thefinder/core/local | localDriver (Node.js / Bun file system) |
| @thefinder/core/s3 | s3Driver for AWS S3, Cloudflare R2, MinIO, Spaces, B2 (no AWS SDK) |
| @thefinder/core/node | toNodeHandler, toExpress, toFastify, toKoa |
| @thefinder/core/sharp | sharpThumbnailer, sharpImages (optional peer sharp) |
| @thefinder/core/client | The browser client used by the UI |
Highlights
- Commands: list, tree, search, create, rename, copy/move (also across volumes), chunked upload, zip download, archive/extract, text and binary save.
- Trash without a database:
.tf-trashper volume, restore, retention. - Version history without a database:
.tf-versionsper volume. Overwritten files keep their previous content; restore, follows renames, retention limits. - Thumbnails: generated on the server and cached per volume (
.tf-thumbs). - Bulk images: resize / compress / convert with
images: sharpImages(); converting keeps the original next to the new file. - Storage stats and cleanup for a dashboard (
stats,cleanup). authorizehook:false→ 403, throwUNAUTHORIZED→ 401,{ readOnly: true }→ a read-only request.onEntriesChangedhook: structuredmoved/trashed/restored/deleted/purged/replacedevents, so a database that refers to files by its own id stays in sync when paths change.- Safe by default: no path traversal, symlinks kept inside the root, CSRF header on writes, zip-slip and zip-bomb guards, HTML/SVG served in a sandbox.
S3, R2, MinIO
import { s3Driver } from "@thefinder/core/s3";
const cloud = s3Driver({
bucket: "my-bucket",
region: "auto", // "auto" for R2
endpoint: "https://<id>.r2.cloudflarestorage.com", // leave empty for AWS
accessKeyId: process.env.S3_KEY!,
secretAccessKey: process.env.S3_SECRET!,
prefix: "uploads/",
});Signing (SigV4) uses Web Crypto, so it also runs on edge runtimes. Uploads use multipart and the server keeps no state between requests.
All theFinder packages
| Package | |
|---|---|
| @thefinder/core | Server engine, drivers, adapters, client (this package) |
| @thefinder/react | The file manager UI and file picker |
| @thefinder/next | Next.js routes, standalone-ready |
| @thefinder/ckeditor | CKEditor 5 / 4 connector |
License
MIT © Alper Koşay
