A modern, feature-rich file server built with Next.js, providing file management, user authentication, permissions, and API access.
- π File Management: Browse, upload, download, rename, and delete files
- π User Authentication: Secure login system with JWT tokens
- π₯ User Management: Admin panel for creating users and managing permissions
- π Permissions System: Granular permissions for upload, delete, and private folder access
- π Private Folders: Password-protected private file access
- π File Sharing: Generate shareable links with optional passwords
- π API Keys: Programmatic access via API keys
- π¨ Modern UI: Clean, responsive interface with dark mode support
- π± Mobile Friendly: Fully responsive design
- πΌοΈ File Previews: Preview images, videos, audio, and text files
- π Search & Filter: Search the whole current directory, filter by type, and use natural filename sorting
- β‘ Large Folders: Bounded filesystem work and 100-item pages keep browsing responsive
- π€ Batch Uploads: Select multiple files or drop them into the explorer; track transfer speed and cancel the queue
- π Create Folders: Create folders directly in the explorer with upload permission
- πΎ Saved Preferences: Remember grid/list view, sorting, and preview settings in this browser
- β¨οΈ Quick Search: Press
/to focus search; refresh a listing without navigating away
- Node.js 22.13 or newer
- npm, yarn, pnpm, or bun
- Clone the repository:
git clone <repository-url>
cd File-Server- Install dependencies:
npm install
# or
yarn install
# or
pnpm install- Create the initial admin user:
node create-user.js <username> <password>This will:
- Create the database and tables if they don't exist
- Create a new admin user with full permissions
- Start the development server:
npm run dev
# or
yarn dev
# or
pnpm dev- Open http://localhost:3000 in your browser
File-Server/
βββ src/
β βββ app/ # Next.js app router pages
β β βββ admin/ # Admin panel
β β βββ api/ # API routes
β β βββ explorer/ # File explorer UI
β β βββ files/ # File serving routes
β β βββ login/ # Login page
β βββ components/ # React components
β β βββ FileExplorer.tsx
β β βββ ui/ # shadcn/ui components
β βββ lib/ # Utilities
β βββ auth.ts # Authentication logic
β βββ db.ts # Database setup
β βββ files.ts # File operations
βββ database/ # SQLite database
βββ files/ # User files
β βββ public/ # Public files
β βββ private/ # Private files
βββ create-user.js # User creation script
Use the create-user.js script to create new admin users:
node create-user.js username passwordAll users created via this script are admins with full permissions.
- Log in as an admin user
- Navigate to
/admin - Use the "Users" tab to:
- Create new users with specific permissions
- Toggle permissions (upload, delete, private access)
- Delete users
- Can Upload: Allows user to upload files
- Can Delete: Allows user to delete files
- Access Private: Allows user to access the private folder
- Admin: Full access to admin panel and all features
- Log in and go to
/adminβ "API Keys" tab - Create a new API key (optionally with a name)
- Important: Copy the key immediately - it won't be shown again!
Include the API key in the Authorization header:
curl -H "Authorization: Bearer fs_YOUR_API_KEY_HERE" \
https://yourserver.com/api/files/publicGET /api/files/[...path]- List files in a directoryGET /api/files/[...path]?download=1- Download a filePOST /api/upload- Upload a file or stage/finalize chunked uploadsDELETE /api/upload?identifier=...- Remove the current user's upload staging filesPOST /api/folders- Create a folder ({ "path": "public", "name": "New folder" })POST /api/delete- Delete a filePOST /api/rename- Rename a filePOST /api/share- Create a shareable linkGET /api/api-keys- List your API keysPOST /api/api-keys- Create a new API keyDELETE /api/api-keys- Delete an API key
The files directory and its public/private roots may be symlinks to other storage volumes. Their startup targets are trusted; nested symlinks must remain inside their respective managed root. Internal staging paths are excluded from file routes.
Folder listings inspect immediate children with at most 32 concurrent metadata reads. Folder size is now null in the listing API and displayed as Folder: recursive totals are no longer calculated while opening a directory. File sizes remain byte counts. Directory responses use private, no-store so refresh reflects disk changes.
The explorer displays up to 100 items per page; search and filters apply to the entire current directory. Sorting is memoized, search is deferred while typing, and folder links do not automatically prefetch every visible directory. Empty folders use the server listing without a duplicate client request.
Text hover previews read at most 8 KiB and display 2,000 characters. File responses stream with byte-range support, ETags, Last-Modified, conditional requests and HEAD handling. HTML and SVG retain download-only behavior.
The uploader processes files in a queue with three parallel 5 MiB chunks per file, bounded retries, live progress, and an explicit finalization step. Each chunk is published atomically; finalization verifies lengths before replacing the destination. Existing filenames are replaced after successful completion. Empty files are supported. Cancellation stops remaining transfers; files already committed remain. Ordinary errors/cancellation remove staged chunks; abrupt browser/server termination can leave staging under files/.temp-uploads/ for manual cleanup when no uploads are active.
For chunked API clients, send identifier, fileName, fileSize, chunkSize, totalChunks, chunkIndex, file and deferMerge=true. After all chunks succeed, send the same metadata with finalize=true and no file. Finalization can be retried with the same identifier. Use DELETE to clear staging after receiving success or cancelling. Clients without deferMerge retain automatic assembly. Upload identifiers are scoped to the authenticated user.
- Right-click on any file β "Share"
- Optionally set a password
- Copy the generated link (format:
/u/randomid) - Share the link - recipients can view/download the file
Admins can set a password for the private folder in /admin β "Settings":
- Set a password to allow URL-based access:
?password=yourpassword - Example:
example.com/files/private/file.png?password=yourpassword
Users with "Access Private" permission can access private files when logged in.
Create a .env.local file:
JWT_SECRET=your-secret-key-change-it
NODE_ENV=productionThe database is automatically created at database/users.sqlite. The create-user.js script will create all necessary tables if they don't exist.
- Framework: Next.js 16.4 / React 19.3 (App Router)
- Database: SQLite (better-sqlite3)
- Authentication: JWT tokens
- UI: React, Tailwind CSS, shadcn/ui
- Icons: Lucide React
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Lint source
npm run typecheck
npm test # Filesystem, upload assembly, and streaming regression tests
npm run test:integration # After build: API tests with isolated temporary files/database
npm run benchmark # Temporary 2400-file fixture; compares uncached recursive listingThe lockfile updates Next.js, React, Radix, Tailwind, SQLite and other dependencies. Unused runtime packages were removed. TypeScript stays on 5.9 and ESLint on 9.39 because the installed Next lint plugins do not yet declare ESLint 10 support. PostCSS is pinned to 8.5.31. npm audit --omit=dev reports no production advisories; five development dependency advisories remain through the lint toolchain's unpatched braces dependency.
- API keys are hashed with SHA-256 before storage
- Passwords are hashed with bcrypt (10 rounds)
- JWT tokens expire after 7 days
- Private folder access requires permission or password
- All file operations are permission-checked
[Add your license here]
[Add contribution guidelines here]