Your Ultimate File Verse
A self-hosted, browser-based file manager built with vanilla JavaScript (ES modules) and PHP. No build step. No framework.
- Browse, navigate, upload, download, rename, delete files and folders
- Copy / move via clipboard "bucket" system
- Recursive search and real-time filter bar
- List, grid, and thumbnail view modes
- Image and video thumbnails (on-demand and cron-batch)
- File preview pane with disk usage info
- Inline text editor with syntax highlighting
- Video / audio player with format conversion (MP4, audio extraction)
- Image resize via ImageMagick
- PDF preview, export, split, and merge
- Directory locking with password protection
- Chunked uploads (100 MB per chunk, unlimited file size)
- Drag-and-drop upload
- IP-based routing — serve different file roots per client IP
- Light / dark / auto theme
- Plugin system with hooks:
previewActions,contextMenuItems,toolbarItems
| Layer | Technology |
|---|---|
| Frontend | Vanilla JS ES Modules |
| Backend API | PHP 7.4+ (fm-api.php) |
| Thumbnails | PHP GD / FFmpeg |
| Styling | CSS custom properties, modular CSS |
| Plugins | ES Module plugins with shared Plugin API |
.
├── index.html Static entry point
├── route-index.php PHP entry point (IP-routed deployments)
├── fm.js Bootstrap: loads config, plugins, boots App
├── fm.css CSS entry: imports all css/ files
├── fm-api.php Backend API — single endpoint
├── fm-thumb-cron.php CLI batch thumbnail generator
├── config.json Runtime config (URLs and paths)
├── route.php IP routing rules — sets BASE_PATH per client
├── ip.php IP diagnostic page
├── files -> /hdd1/files Symlink to storage root
├── _thumb/ Generated WebP thumbnails
├── js/ Core JS modules
├── css/ Modular CSS files
├── php/ PHP utilities (fm-thumb.php)
└── plugins/
├── plugin-api.js Public plugin surface
├── branding/
├── editable/
├── imgtool/
├── pdftool/
└── videotool/
| Component | Purpose |
|---|---|
PHP 7.4+ with gd |
Image thumbnail generation |
| FFmpeg | Video thumbnails, video conversion plugin |
| ImageMagick | Image resize plugin |
| poppler-utils | PDF plugin (pdfinfo, pdftoppm, etc.) |
| Nginx / Apache + PHP-FPM | Web server |
Edit config.json to set URL paths as seen by the browser:
{
"api": "/fm-api.php",
"thumb_url": "/_thumb",
"files_path_url": "/files",
"plugins_url": "/plugins"
}BASE_PATH (the server-side files root) is resolved automatically from route.php. For simple deployments it defaults to __DIR__ . /files. For IP-routed deployments, edit route.php to map IP ranges to subdirectories:
$routes = [
['range' => '192.168.10.', 'files_path_url' => '/files/warnet'],
['exact' => '10.122.2.67', 'files_path_url' => '/files/tatata'],
];php fm-thumb-cron.php # generate all missing thumbnails
php fm-thumb-cron.php --dry-run # preview without writing
php fm-thumb-cron.php --path=/photos
# nightly at 2 AM
0 2 * * * php /var/www/fm/fm-thumb-cron.php >> /var/log/fm-thumb.log 2>&1Plugins live in plugins/{name}/ and follow the naming convention {name}-script.js, {name}-style.css, {name}-function.php.
import { registerPlugin, Api, Icons, Dialog, notify, refresh, getCwd } from '../plugin-api.js'
registerPlugin({
name: 'my-plugin',
previewActions(item, el) { ... },
contextMenuItems(item) {
return [{ icon: Icons.edit, label: 'My Action', fn: () => { ... } }]
},
toolbarItems() {
return [{ icon: Icons.upload, title: 'My Tool', id: 'btn-my-tool', fn: () => { ... } }]
},
})| Doc | Contents |
|---|---|
| Installation | Requirements, server setup, IP routing, first-boot checklist |
| User Guide | Navigation, uploads, bucket, keyboard shortcuts, themes |
| Architecture | Module map, boot sequence, data contracts, CSS layers |
| API Reference | All fm-api.php actions — request/response shapes, error codes |
| Plugin Development | Full plugin API reference with examples |
| Built-in Plugins | branding, editable, videotool, imgtool, pdftool |
| Thumbnails | Thumbnail system, cron, permissions, lifecycle |
| Changelog | Running changelog |
MIT