製品 — FluxFiles

機能

モダンなファイルマネージャーに必要なすべて

柔軟性を求める開発者のために構築。

マルチストレージ

ローカル、AWS S3、Cloudflare R2, SFTP — Flysystem v3経由。設定で切替、コード変更不要。

どこにでも埋め込み

iframe + postMessage SDK。スタンドアロンUIはAlpine.js(ビルド不要)。どのフレームワークでも可。

JWT認証 + スコーピング

ユーザーごとのパスプレフィックス、権限、ディスクホワイトリスト、owner-onlyモード——viewer/editor/adminのロールプリセットから始めることも可能。

ACLロールプリセット

viewer/editor/admin/superadminのプリセットからトークンを発行——1つのパラメータで適切な権限・ディスク・スコープのクレームが展開され、手動で組み立てる必要がありません。

AI自動タグ

Claude / OpenAI vision — altテキスト、タイトル、タグを自動生成。

画像クロップ

アスペクト比プリセット付きインラインクロップツール。

画像最適化

WebPバリアント自動生成 — サムネイル、中、大。

署名付きアップロード

ブラウザからS3/R2に直接アップロード — サーバー帯域ゼロ。

チャンクアップロード

10MB超ファイル向けS3マルチパート。

全文検索

ファイル名・タイトル・タグを索引検索——デフォルトはファイルベース、オプトインで自前のSQLデータベースをバックエンドに選択可能。

DBバックエンドのメタデータ

オプトインのFLUXFILES_STORAGE_BACKEND=dbモード——メタデータ、検索/フォルダインデックス、監査ログがJSONサイドカーの代わりに自前のMySQL/PostgreSQL/SQLiteに保存されます。ファイル本体はどちらの場合もストレージ側に残ります。

一括操作

複数選択して移動、コピー、削除、ダウンロード。

クロスディスク転送

ローカル ↔ S3 ↔ R2間のコピー/移動。

ゴミ箱

復元可能な削除、自動パージ。

SEOメタデータ

タイトル、alt、キャプション、タグ — クラウドはS3オブジェクトメタデータ、ローカルはsidecar JSON。全文検索。

ダークモード

UIとSDKでライト/ダーク/自動。

16言語

デフォルトは英語。SDK、URL (?locale=)、またはFLUXFILES_LOCALEで指定。アラビア語はRTL。

監査ログ

すべての書き込み操作を記録。

レート制限

ユーザーごとのトークンバケット。

ストレージクォータ

JWTクレームによるユーザーごとの制限。

BYOBバケット

ユーザー自身のS3/R2 — 認証情報はJWT内で暗号化(AES-256-GCM)。

重複検出

SHA-256一致で冗長アップロードをスキップ(強制上書き除く)。

SDKトークン更新

401時にonTokenRefresh — 更新の集約、再試行、updateToken()で事前更新。

バケットドクター

任意の S3/R2 ディスクを診断——認証情報、読み/書き/削除、署名付き URL、CORS、マルチパート——貼り付けるだけの IAM・CORS 修正付き。BYOB バケットを数分で導入。

SFTP ディスク

S3/R2 に次ぐ3つ目のドライバー。あらゆる VPS や共有ホストをファイル管理に。

コード / 設定エディタ

設定・テキストファイル(wp-config.php、.env など)をブラウザで編集(cPanel風)。

Zip と展開

選択をzipでダウンロード、またはその場で展開。zip-slip・爆弾対策済み。

ウォーターマーク

プレビュー保護のため文字やロゴの透かしを動的に付与。元ファイルは無変更。

オンデマンド WebP + AVIF

1つの URL で任意サイズの画像をキャッシュ済み AVIF/WebP として配信(Accept ネゴシエーション)、レスポンシブ srcset 付き。

SFTP 権限

cPanel風ダイアログでSFTPディスクのUnix権限(chmod)を変更。

SSHターミナル

無料の terminal_pty_url クレームで、SFTP ディスク上のアプリ内ターミナルとして独自の ttyd / gotty / wetty を埋め込めます。FluxFiles 自体はシェルを同梱していません。

ワンクリックGitデプロイ

ファイルマネージャーからSFTPサーバー上のGitリポジトリをpull・reset——固定形式で任意シェルではなく、hooksはデフォルトで無効。

使用状況ダッシュボード

ストレージを一目で把握。容量に加え、種類別・フォルダ別の内訳。

メディアプレビュー

画像・動画・音声・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.

本番運用に向けて:32 バイト以上の FLUXFILES_SECRET と FLUXFILES_ALLOWED_ORIGINS(または FLUXFILES_FRAME_ANCESTORS)を設定してください。パッケージのルートをドキュメントルートにし、nginx で /_fluxfiles/ と .env へのアクセスを拒否します。メインの JWT を URL に含めないでください。アダプターは postMessage で渡します。 DEPLOYMENT.md

対応フレームワーク

Laravel WordPress React / Next.js Vue / Nuxt CKEditor 4 CKEditor 5 TinyMCE Summernote Any framework

インテグレーション

あなたのスタックに差し込めるアダプター

公式アダプターで、すでに使っているフレームワークやエディターに FluxFiles をネイティブ統合できます。

CKEditor や TinyMCE をご自身のストレージで使えます。CKBox や Tiny Drive の契約は不要です。FluxFiles はファイルの参照と挿入のためのツールバーボタンを追加するもので、これらの製品の機能を一対一で置き換えるものではありません。

Laravel
PHP
WordPress
Plugin
React
Component
Vue / Nuxt
Component
CKEditor 4
Plugin
CKEditor 5
Plugin
TinyMCE
Plugin
Summernote
Plugin

組み込み

数行で組み込み

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を選ぶ理由

他が忘れたものを構築

スワイプで比較
機能 FluxFiles elFinder Laravel-FM RichFilemanager Responsive FM
S3 + R2 + Local + SFTP ✓ ⚠ ⚠ ⚠ ✗
あらゆるフレームワークに埋め込み ✓ ⚠ ✗ ⚠ ✗
JWT認証 + スコーピング ✓ ✗ ✗ ✗ ✗
SEOメタデータ ✓ ✗ ✗ ✗ ✗
AI自動タグ ✓ ✗ ✗ ✗ ✗
画像クロップ ✓ ✓ ✗ ✗ ✗
チャンクアップロード ✓ ✗ ✗ ✗ ✗
全文検索 ✓ ✗ ✗ ✗ ✗
ダークモード ✓ ✗ ⚠ ✗ ✗
16言語 ✓ ✓ ✗ ✗ ✗
PHP ≥ 8.1 ✓ ✓ ✗ ✓ ✓
積極的にメンテナンス中 ✓ ✓ ⚠ ✗ ✗
モダンUI ✓ ✗ ⚠ ✗ ✗
機能 FluxFiles Filestack Uploadcare Cloudinary Supabase Storage
セルフホスト(自社インフラで動作) ✓ ✗ ✗ ✗ ⚠
BYOB——各顧客が自分のバケット ✓ ⚠ ⚠ ✗ ✗
埋め込み可能なファイルマネージャー UI ✓ ✓ ✓ ⚠ ✗
オープンソース(MIT) ✓ ✗ ✗ ✗ ✓
ストレージ/アップロード課金の SaaS 料金なし ✓ ✗ ✗ ✗ ⚠
マルチストレージ(S3 / R2 / ローカル) ✓ ⚠ ✗ ✗ ✗
テナント単位のトークンスコープを標準装備 ✓ ⚠ ⚠ ⚠ ⚠

比較は一般的なデフォルト提供内容を反映しています。各製品はそれぞれの領域で優れています。FluxFiles のニッチは、埋め込み可能・セルフホスト・自前バケットの組み合わせです。

比較データはNovember 2026時点のもので、第三者による非公式な比較です——修正が必要な場合はGitHubリポジトリでお知らせください。

FAQ

よくある質問

認証はどのように機能しますか?
ステートレスな JWT(HS256)です。権限・ディスク・パス範囲・上限などのきめ細かいクレームを付けてサーバー側でトークンを発行するため、各ユーザーは許可された範囲だけを見られます。
ユーザーに FluxFiles のアカウントは必要ですか?
不要です。FluxFiles はあなたのアプリが発行する JWT を信頼するので、既存の認証にそのまま組み込めます。別個のユーザー管理は不要です。
動かすには何が必要ですか?
PHP 8.1+(8.1〜8.5 でテスト済み)と gd、curl、json、openssl、mbstring、fileinfo(展開機能には zip も)および Composer 2、または Docker イメージ ghcr.io/thai-pc/fluxfiles。ディスクを指定し、シークレットと許可オリジンを設定して起動するだけで、小規模な VPS でも動作します。
ユーザーごとに異なる権限を与えられますか?
はい。細かいクレーム(読み取り/書き込み/削除、ディスク、パスプレフィックス、アップロード制限、許可する拡張子、owner-only)でトークンを発行するか、4つの組み込みロールプリセット(viewer、editor、admin、superadmin)のいずれかを使えば、クレームを一つずつ列挙せずに1行でトークンの範囲を決められます。
データベースを運用する必要がありますか?
いいえ。デフォルトでは、すべてのメタデータ(ファイル情報、検索インデックス、監査ログ)はファイルと一緒にJSONサイドカーとして保存されます — 別途プロビジョニングやバックアップの必要はありません。この管理情報を自前のMySQL、PostgreSQL、SQLiteに置きたい場合は、オプションのFLUXFILES_STORAGE_BACKEND=dbモードでそちらに移せます。いずれの場合もファイル本体は常にお使いのストレージに残ります。
利用に制限はありますか?
コア自体には人為的な制限はありません — 月間アクティブユーザー数の上限も、強制的なアップグレード催促もありません。ユーザーごとのストレージクォータ、アップロードサイズ/拡張子の制限、組み込みのレートリミッター(デフォルトで1分あたり読み取り60回/書き込み10回、設定変更可能)など、制限はすべてJWTクレームでご自身で設定します。