v0.41.0
filex v0.41.0
Self-hosted file manager — Go single binary + multi-framework frontend.
Download a binary below, or pull a Docker image:
docker pull ghcr.io/brf-tech/filex:slim-v0.41.0
docker pull ghcr.io/brf-tech/filex:full-v0.41.0What changed
⚠ 0.40.0 was never finished. Its npm packages and git tag were published,
but the container images, the binaries, the desktop builds and the GitHub
Release were not — so the app-store manifests that pinnedv0.40.0pointed
at an image that does not exist. This release is the first complete one after
0.39.1, it carries everything listed under 0.40.0 below except the Drive
theme (removed here — see Changed), and it moves every pin to itself.
Added
-
A new face for the whole product. The explorer was rebuilt around the
end-user shell @alfatm designed on top of filex
and put up for review in #14 — measured screen by screen and adopted as
filex's own look rather than offered as a theme. One layout for the operator
and the end user alike, in the admin app, the desktop app and every embed:
a full-width top bar with the product mark, one search field, a + New
menu, a 192px navigation panel with Home · Shared with me · Recent ·
Starred · Trash, the storages and the connection guides, a breadcrumb row
with the view switcher, a Type · People · Modified · Size filter row with
a sort control, a selection bar that replaces the filter row while anything is
ticked, and an info panel split into Details and Activity. The palette,
metrics, type scale and control heights are--fe-*tokens, so a theme or a
host page restyles all of it without forking a stylesheet. The tab strip, the
split pane, the gallery view, the palettes and the keyboard editor — filex's
own additions — are kept. -
Home is a view inside the explorer, not a page beside it: your storages,
what you opened last and what you starred, under the same panel and header as
the files. It is where everybody lands, administrators included; an operator
who prefers the dashboard picks it under User settings → Preferences →
Start page. -
User settings, one dialog behind the avatar: profile and photo, language,
time zone (a search field with the offset and local time on each row), start
page, light/dark and palette, density, per-folder view memory, notification
switches, password and two-factor. Language and theme moved here from the
header, so no preference has two controls. -
A listing that behaves like a table. Resize a column, hide one, drag one
to a new place; the table scrolls sideways when the columns outgrow the pane,
with the actions column pinned right, instead of dropping a column. Name is an
ordinary column you can narrow. The grid and the list obey the same sort —
it used to be private state inside the list, so switching views reordered the
rows under you. -
Per-folder view memory — optional, from user settings. The view mode and
sort of each folder you set up, stored per person on the server
(GET/PUT /api/files/manager/view-prefs, migration00039), so it follows you
to another machine and never leaks to anyone else looking at the same folder.
Capped and least-recently-used. An embed turns it off with
rememberFolderView: false. -
Who owns a file. Every node records its owner and its last writer
(migration00038); the list has an Owner column and the filter row a
People filter; quota counts against the owner. A storage scan no longer
attributes a whole bucket to whoever pressed Scan now. Search hits carry the
storage name and the owner too, which lifts the old single-storage limit on
content search in the advanced search dialog. -
Download a selection as one archive. Pick several files and folders and
Download streams a ZIP built on the fly (POST /api/files/archive/download
mints a single-use ticket,GET /z/<token>streams it): nothing is written
into your storage, nothing is buffered in the tab, and a 700 MB archive costs
the server under a megabyte. Every member is re-checked against the caller's
own permissions on the server. -
Move to / Copy to, with a folder chooser that spans every storage, lists a
read-only folder as read-only, and refuses a destination you cannot write to —
and the server refuses it regardless of what the dialog offered. -
New document under + New: a Word, Excel, PowerPoint or OpenDocument
file, or any text or code format — name it, choose where it goes, and it opens
in the editor that handles it. The Office templates are minimal valid
documents compiled into the binary (verified by LibreOffice and by
OnlyOffice's own converter), so this works on the slim image; a type this
deployment could not then open is not offered, and the dialog says why. -
Thumbnails you can read. A PDF shows its first page, top-anchored so the
title is in the card; a video its first frame that is not black; an Office
document its rendered first page; a text, code or CSV file fills the card with
its own content. A server missing ffmpeg, ghostscript or LibreOffice now says
so in its log at boot instead of quietly drawing coloured rectangles. -
Date headings in every view. A listing sorted by Modified groups itself
under Today · Yesterday · This Week · This Month · September 2026 — in
the list, the grid and the gallery. The ladder lives in one module
(packages/core/src/lib/dateGroups.ts) and all three views read it.- ⚠ A heading is drawn only when it is true. Any other sort key draws
none, and neither does a search's ranked answer. - ⚠ "This Week" is the six days before yesterday, not a calendar week.
- In the grid the date headings replace "Files" rather than stacking on
it; "Folders" stays as one run at the top. - The boundary between today and yesterday is midnight in the viewer's
chosen time zone, not the browser's.
- ⚠ A heading is drawn only when it is true. Any other sort key draws
-
Tags you can follow. A tag chip in the details panel opens the tag view:
everything carrying that tag, folders as well as files, across storages, with
the ordinary filter row and sort on top. -
A notification bell in the top bar, for every account. Non-admins were
raised browser notifications but had no way to open the list, mark one read
or follow one to what it was about. -
The desktop-app offer is a chip in the corner of the app, not a card over
the file listing, with a permanent home under User settings. "Do not show this
again" is remembered against the account, not the browser. -
Browser notifications, and a notification opens the thing it is about.
-
The split pane is one pane component rendered twice, so the right-hand
pane has the same breadcrumb, filter row, sort, view switcher and selection
bar as the left — it used to be a separate, thinner implementation. -
Time zones resolve the same way everywhere. One ordered list decides the
zone every date is printed in: the viewer's own pick → the host page's
config.timeZone→ the account behind the token → the device. The account
tier applies only to a person's token; anapptoken shared by many visitors
never imposes one account's zone on all of them. An embed gains a Time zone
row in its⋯menu, stored in the browser, because it has no settings dialog;
the web app and an embed use the same picker and the same resolver, so the two
can no longer disagree. New:config.timeZone, and atime-zoneattribute on
<filex-explorer>. -
Operator custom CSS. A stylesheet pasted under Settings is served with
the branding payload and applied last on every browser surface, the sign-in
page included, so an installation can override the--fe-*tokens without
forking anything. It is capped at 64 KB, stored as one global row (in
multi-tenant mode only the supertenant may set it), and injected as the text
of a single<style>element, never parsed as HTML. See
docs/INTEGRATION.md. -
Home tells everyone how full a storage is, not only an administrator:
GET /api/files/quota/storagesanswers the same figure the admin storage list
carries, for the storages the caller may see and nothing about the others. -
Recovery sign-in for SSO-only installations. With no
localdriver
enabled, the administrator filex created at installation can still sign in
with its password — and no other account can — so an identity provider that
is down, a client secret that expired or a broken realm no longer locks out
the one person who can fix it. The login page offers it behind an
Administrator recovery sign-in link; two-factor still applies and every
such sign-in is logged at WARN. On by default,FILEX_AUTH_RECOVERY_LOGIN=false
turns it off. Installations from before this release get the account worked
out once at startup: the oldest administrator that has a local password. See
docs/SSO.md. -
Brand config for embeds:
config.brand(name,markUrl). A host
cannot fill any slot in<filex-explorer>— Vue projects light DOM only
through a shadow root and the element deliberately has none — so this is how
an embed puts its mark in the corner. -
A duplicate-code gate (
scripts/dup-scan.mjs, run by the web test suite):
near-duplicate fragments, the same concept implemented outside its one home,
and listing surfaces that build their own chrome. The rule and how to answer it
are indocs/CONTRIBUTING.md.
Changed
-
⚠⚠
uiProfile: 'drive'is removed. It shipped as a third profile in
0.32.0 and became an alias of'simple'during this cycle; there are now two
profiles,'standard'and'simple', and no alias of either.If you pass
'drive', pass'simple'instead. An unrecognised value —
a typo, or this retired name — resolves to'standard'(the documented
default) and logs one console line naming it. That direction is deliberate:
mapping the retired name onto'simple'would be the alias again under
another name, and it would also mean a plain typo silently REDUCED somebody's
UI, which looks like features going missing and points at nothing. The
argument is written out inpackages/core/src/lib/uiProfile.ts. -
⚠ The Drive theme added in 0.40.0 is removed. Its palette became the
product's stock palette, so the theme had nothing left to change. -
The product colour is blue (
#2f6ceblight,#5b8cffdark) — the mark,
the favicon and PWA icon, the admin panel, the desktop app, the public share
page and the project site all moved off indigo together. -
Byte sizes are decimal everywhere (1 KB = 1000 B). The explorer used 1024
and the admin panel 1000, so the same file read1.43 MBin one and1.5 MB
in the other; a quota typed as 10 GB read back as 9.31 GB in the side panel.
Turkish gets its own decimal separator. -
The sign-in page follows the operating system's light/dark setting and the
browser's language; both are chosen in user settings once you are in. -
/admin/profileopens user settings. The profile page is gone — every
field it had lives in the user settings dialog, which a non-admin can open
too. The address keeps working, because the startup banner and
<data>/.first-run.txton existing installs still point a new operator at it. -
"Copy node id" left the right-click menu and the selection bar; the id is
in the details panel, beside Path and ETag, one click to copy. -
@brftech/filex-reactneeds no stylesheet import — the look is injected
by the bundle. A bundler build needs the optional viewer packages
externalized; seedocs/INTEGRATION.md. -
⚠ MySQL needs 8.0.17 or newer, MariaDB 11.4 or newer. Migration
00041
compares file names byte for byte withutf8mb4_0900_bin, which MySQL added
in 8.0.17, and it rebuilds thenodestable — on a large catalogue that takes
as long as anALTER TABLEof that table takes on your server. The previous
documentation promised MariaDB 10.5.2; MariaDB 10.x never got past migration
00001. Measured versions are listed in
docs/DATABASES.md.
This release has more to it than fits on one page. The rest of the
entry — and every earlier release — is in CHANGELOG.md.
Verify: sha256sum -c checksums.txt
- Documentation — https://docs.filex.sh
- Report a bug — https://github.com/BRF-Tech/filex/issues
- Full changelog — https://github.com/BRF-Tech/filex/blob/main/CHANGELOG.md
- Every release — https://github.com/BRF-Tech/filex/releases