Продукт — FluxFiles
Всё, что нужно современному файловому менеджеру
Создан для разработчиков, которым нужна гибкость.
Мульти-хранилище
Локальное, AWS S3, Cloudflare R2, SFTP через Flysystem v3 — меняйте в конфиге без правки кода.
Встраивайте куда угодно
iframe + postMessage SDK. Автономный UI на Alpine.js (без сборки). С любым фреймворком.
JWT авторизация + скоупинг
Префикс пути, права, белый список дисков, режим только владелец — или начните с готового набора прав viewer/editor/admin.
Пресеты ролей ACL
Выпускайте токены из пресетов viewer/editor/admin/superadmin — один параметр разворачивает нужные claims прав, дисков и области доступа вместо ручной сборки.
AI авто-теги
Claude / OpenAI vision — автоматический alt-текст, заголовок, теги.
Обрезка изображений
Инструмент обрезки с предустановками пропорций.
Оптимизация изображений
Автоматические WebP-варианты — миниатюра, средний, большой.
Предподписанные загрузки
Браузер загружает напрямую в S3/R2 — нулевая нагрузка на ваш сервер.
Загрузка частями
S3 multipart для файлов > 10МБ.
Полнотекстовый поиск
Индексированный поиск по именам, заголовкам, тегам — по умолчанию на файлах, либо ваша собственная SQL-база как опциональный бэкенд.
Метаданные в БД
Опциональный режим FLUXFILES_STORAGE_BACKEND=db — метаданные, индекс поиска/папок и журнал аудита хранятся в вашей собственной базе MySQL/PostgreSQL/SQLite вместо JSON-файлов. Байты файлов в обоих случаях остаются в хранилище.
Массовые операции
Множественный выбор: перемещение, копирование, удаление, скачивание.
Кросс-диск перенос
Копирование/перемещение между Локальным ↔ S3 ↔ R2.
Корзина
Восстановимое удаление с автоочисткой.
SEO метаданные
Заголовок, alt, подпись, теги — метаданные S3 (облако) или sidecar JSON (локально). Полнотекстовый поиск.
Тёмный режим
Светлая / тёмная / авто в UI и SDK.
16 языков
По умолчанию английский. Локаль через SDK, URL (?locale=) или FLUXFILES_LOCALE. RTL для арабского.
Журнал аудита
Все действия записи логируются.
Ограничение скорости
Token bucket для каждого пользователя.
Квота хранилища
Лимиты для каждого пользователя через JWT claims.
BYOB бакеты
Свой S3/R2 пользователя — учётные данные в JWT (AES-256-GCM).
Обнаружение дубликатов
Совпадение SHA-256 пропускает лишние загрузки кроме принудительной перезаписи.
Обновление токена SDK
onTokenRefresh при 401 — объединённое обновление, повтор, updateToken().
Bucket Doctor
Диагностика любого диска S3/R2 — учётные данные, чтение/запись/удаление, presign, CORS, multipart — с готовыми к вставке исправлениями IAM и CORS. Подключайте BYOB-бакеты за минуты.
Диск SFTP
Третий драйвер после S3/R2 — превратите любой VPS или хостинг в файловый менеджер.
Редактор кода / конфигов
Редактируйте текст и конфиги (wp-config.php, .env) в браузере, как в cPanel.
Zip и распаковка
Скачайте выбранное как zip или распакуйте архив — защита от zip-slip и бомб.
Водяной знак
Накладывайте текст или логотип на лету для защиты превью — оригинал не меняется.
WebP + AVIF по запросу
Отдавайте любой размер изображения как кэшированный AVIF/WebP по одному URL (согласование через Accept), с готовым адаптивным srcset.
Права SFTP
Меняйте права Unix (chmod) на SFTP-дисках через диалог в стиле cPanel.
SSH-терминал
Встройте собственный ttyd / gotty / wetty как терминал внутри приложения на SFTP-дисках через бесплатный клейм terminal_pty_url — собственной оболочки в FluxFiles нет.
Git-деплой в один клик
Pull и reset Git-репозитория на вашем SFTP-сервере прямо из файлового менеджера — фиксированная форма, не произвольная оболочка, хуки по умолчанию отключены.
Панель использования
Хранилище с первого взгляда — квота и разбивка по типам и папкам.
Предпросмотр медиа
Встроенный просмотр фото, видео, аудио и PDF; приватные локальные медиа — безопасно.
Запуск за 2 минуты
composer require fluxfiles/fluxfiles
cp vendor/fluxfiles/fluxfiles/.env.example vendor/fluxfiles/fluxfiles/.env # vendor/fluxfiles/fluxfiles/.env (read only from inside the package)
# Real environment variables win over this file and are preferred in production
# (Composer may remove a vendor .env on update).
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com <?php
require_once 'vendor/autoload.php';
// embed.php is not autoloaded — require it for fluxfiles_token()
require_once 'vendor/fluxfiles/fluxfiles/embed.php';
$token = fluxfiles_token([
'user' => 'user-123',
'perms' => ['read', 'write', 'delete'],
'disks' => ['local'], // s3 / r2 need their own credentials in .env
'prefix' => 'user-123/',
'ttl' => 3600,
]); php vendor/bin/fluxfiles serve --port=8080
# then open http://127.0.0.1:8080/public/ composer require fluxfiles/laravel
php artisan vendor:publish --tag=fluxfiles-config
php artisan storage:link # .env — proxy mode is the default: the API runs through your Laravel routes,
# no separate FluxFiles server is needed.
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
# Only for FLUXFILES_MODE=standalone (FluxFiles on its own server):
# FLUXFILES_MODE=standalone
# FLUXFILES_ENDPOINT=https://fm.yourdomain.com <?php
// app/FluxFiles/TenantClaims.php — REQUIRED: without a claims resolver
// <x-fluxfiles> renders "not available".
namespace App\FluxFiles;
use FluxFiles\Laravel\ClaimsResolver;
use Illuminate\Contracts\Auth\Authenticatable;
class TenantClaims implements ClaimsResolver
{
public function resolve(Authenticatable $user): array
{
return [
'prefix' => 'users/' . $user->getAuthIdentifier(),
];
}
} // config/fluxfiles.php
'claims_resolver' => \App\FluxFiles\TenantClaims::class, // Laravel 11 / 12 — bootstrap/app.php: exclude the proxy routes from CSRF (else 419)
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: ['api/fm/*']);
})
// Laravel 10 — app/Http/Middleware/VerifyCsrfToken.php
// protected $except = ['api/fm/*']; <x-fluxfiles disk="local" mode="picker" height="600px" /> # Not yet on WordPress.org — install the release zip:
# 1. Download fluxfiles-<version>.zip from https://github.com/thai-pc/fluxfiles/releases
# 2. Plugins -> Add New -> Upload Plugin -> Activate
# 3. Settings -> FluxFiles: set the JWT secret (>= 32 bytes) and storage
# 4. Add the shortcode (or the FluxFiles block) to any page or post: [fluxfiles] npm install @fluxfiles/node # Node >= 16 // Express / Next.js route — mint a token from your JS backend (no PHP)
import { createToken } from '@fluxfiles/node';
app.get('/fluxfiles-token', (req, res) => {
const token = createToken({
secret: process.env.FLUXFILES_SECRET, // >= 32 bytes
userId: req.user.id,
perms: ['read', 'write', 'delete'],
prefix: `users/${req.user.id}`,
ttl: 3600,
});
res.json({ token });
}); pip install fluxfiles-token # FastAPI / Django / Flask route — mint a token from your Python backend (no PHP)
import os
from fastapi import Depends
from fluxfiles_token import create_token
@app.get("/fluxfiles-token")
def fluxfiles_token(user=Depends(current_user)):
token = create_token(
secret=os.environ["FLUXFILES_SECRET"], # >= 32 bytes
user_id=user.id,
perms=["read", "write", "delete"],
prefix=f"users/{user.id}",
ttl=3600,
)
return {"token": token} {
"mcpServers": {
"fluxfiles": {
"command": "npx",
"args": ["-y", "@fluxfiles/mcp"],
"env": {
"FLUXFILES_URL": "<your FluxFiles URL>",
"FLUXFILES_TOKEN": "<scoped JWT>"
}
}
}
} # Claude Code (Node >= 18)
claude mcp add fluxfiles -e FLUXFILES_URL=<your FluxFiles URL> -e FLUXFILES_TOKEN=<scoped JWT> -- npx -y @fluxfiles/mcp # Read-only by default. Opt in to writes:
FLUXFILES_MCP_WRITE=1
# and to move_to_trash:
FLUXFILES_MCP_DELETE=1 Агент может работать только с тем, что разрешает его JWT, — его дисками, префиксом пути и правами. Выдайте ему узкий токен только для чтения.
npm install fluxfiles <!-- or load a pinned CDN build (never @latest) -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script> <div id="file-picker" style="height:600px"></div>
<script>
FluxFiles.open({
endpoint: 'https://your-fluxfiles-host',
token: 'eyJhbGci...', // JWT minted by your backend
disk: 'local',
mode: 'picker',
container: '#file-picker',
onSelect: function(file) {
console.log('Selected:', file.url);
},
async onTokenRefresh() {
const r = await fetch('/api/auth/refresh-fluxfiles-token');
const { token } = await r.json();
return token;
}
});
</script> npm install @fluxfiles/react import { FluxFilesModal } from '@fluxfiles/react';
<FluxFilesModal
open={open}
endpoint="https://your-api.com"
token={token}
onSelect={(file) => console.log(file)}
onClose={() => setOpen(false)}
/> npm install @fluxfiles/vue <script setup>
import { FluxFilesModal } from '@fluxfiles/vue';
</script>
<FluxFilesModal
v-model:open="open"
endpoint="https://your-api.com"
:token="token"
@select="onSelect"
@close="open = false"
/> docker run -p 8080:80 \
-e FLUXFILES_SECRET="$(openssl rand -hex 32)" \
-e FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com \
-v fluxfiles-data:/app/packages/core/storage \
ghcr.io/thai-pc/fluxfiles:1.1 # UI: http://localhost:8080/public/ git clone https://github.com/thai-pc/fluxfiles.git
cd fluxfiles/packages/core
composer install
cp .env.example .env # packages/core/.env — the placeholder secret is rejected, set a real one
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=http://localhost:8080 # print dev tokens (run from the repo root)
php packages/core/tests/generate-token.php php -S localhost:8080 router.php
# UI: http://localhost:8080/public/index.html?token=<token>
# ?token= is dev-only — it is stripped from the URL on boot.
# Real apps pass the JWT via the SDK / postMessage, never in a URL. Перед запуском в продакшен: задайте FLUXFILES_SECRET длиной не менее 32 байт и FLUXFILES_ALLOWED_ORIGINS (или FLUXFILES_FRAME_ANCESTORS). Сделайте корень пакета document root и закройте в nginx /_fluxfiles/ и .env. Никогда не передавайте основной JWT в URL — адаптеры отправляют его через postMessage. DEPLOYMENT.md
Работает с
Интеграции
Готовые адаптеры для вашего стека
Официальные адаптеры нативно встраивают FluxFiles во фреймворки и редакторы, которыми вы уже пользуетесь.
Используйте CKEditor или TinyMCE со своим хранилищем — подписка на CKBox или Tiny Drive не нужна. FluxFiles добавляет кнопку на панель инструментов для просмотра и вставки файлов; это не замена этих продуктов по функциям один к одному.
Встраивание
Встройте в несколько строк
Подключите fluxfiles.js, передайте JWT, выпущенный на сервере, и разместите полноценный файловый менеджер — или модальное окно выбора файлов — на любой странице.
<!-- npm install fluxfiles, or a pinned CDN build -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script>
FluxFiles.open({
endpoint: 'https://fm.example.com',
token: 'eyJhbGci...', // JWT from your backend
disk: 'local',
mode: 'picker', // select & close
theme: 'auto',
onSelect(file) {
// { url, key, name, size, disk, meta, variants }
document.querySelector("#img").src = file.url;
},
}); <div id="fm" style="height:600px"></div>
FluxFiles.open({
endpoint: 'https://fm.example.com',
token: 'eyJhbGci...',
mode: 'browser', // full manager, stays open
container: '#fm', // omit for a modal overlay
disks: ['local', 's3', 'r2'],
});
FluxFiles.on('FM_EVENT', (e) => console.log(e.event));
FluxFiles.navigate('/photos/2024'); import { FluxFilesModal } from '@fluxfiles/react';
function Picker({ open, setOpen, token }) {
return (
<FluxFilesModal
open={open}
endpoint="https://fm.example.com"
token={token}
onSelect={(file) => console.log(file.url)}
onClose={() => setOpen(false)}
/>
);
} Токены выпускаются на сервере — никогда не передавайте секрет в браузер.
Создан для того, о чём другие забыли
| Функция | FluxFiles | elFinder | Laravel-FM | RichFilemanager | Responsive FM |
|---|---|---|---|---|---|
| S3 + R2 + Локальное + SFTP | ✓ | ⚠ | ⚠ | ⚠ | ✗ |
| Встраивание в любой фреймворк | ✓ | ⚠ | ✗ | ⚠ | ✗ |
| JWT авторизация + скоупинг | ✓ | ✗ | ✗ | ✗ | ✗ |
| SEO метаданные | ✓ | ✗ | ✗ | ✗ | ✗ |
| AI авто-теги | ✓ | ✗ | ✗ | ✗ | ✗ |
| Обрезка изображений | ✓ | ✓ | ✗ | ✗ | ✗ |
| Загрузка частями | ✓ | ✗ | ✗ | ✗ | ✗ |
| Полнотекстовый поиск | ✓ | ✗ | ✗ | ✗ | ✗ |
| Тёмный режим | ✓ | ✗ | ⚠ | ✗ | ✗ |
| 16 языков | ✓ | ✓ | ✗ | ✗ | ✗ |
| PHP ≥ 8.1 | ✓ | ✓ | ✗ | ✓ | ✓ |
| Активно поддерживается | ✓ | ✓ | ⚠ | ✗ | ✗ |
| Современный UI | ✓ | ✗ | ⚠ | ✗ | ✗ |
| Возможность | FluxFiles | Filestack | Uploadcare | Cloudinary | Supabase Storage |
|---|---|---|---|---|---|
| Self-hosted (работает в вашей инфраструктуре) | ✓ | ✗ | ✗ | ✗ | ⚠ |
| BYOB — собственный бакет каждого клиента | ✓ | ⚠ | ⚠ | ✗ | ✗ |
| Встраиваемый UI файлового менеджера | ✓ | ✓ | ✓ | ⚠ | ✗ |
| Открытый код (MIT) | ✓ | ✗ | ✗ | ✗ | ✓ |
| Без SaaS-платы за хранение / за загрузку | ✓ | ✗ | ✗ | ✗ | ⚠ |
| Мультихранилище (S3 / R2 / локально) | ✓ | ⚠ | ✗ | ✗ | ✗ |
| Встроенное ограничение токена по арендатору | ✓ | ⚠ | ⚠ | ⚠ | ⚠ |
Сравнение отражает типичные предложения по умолчанию; каждый продукт силён в своей области. Ниша FluxFiles — сочетание встраиваемости, self-hosted и bring-your-own-bucket.
Сравнение актуально на November 2026, подготовлено независимо — сообщите об ошибке через репозиторий на GitHub.
Вопросы и ответы