No description
  • Go 56.8%
  • TypeScript 40.3%
  • SCSS 2.3%
  • Makefile 0.2%
  • Dockerfile 0.1%
Find a file
Gykes bdee3c83d3
New/RFC: Saved Filter List refactor (#7224)
* Add rename and an operations menu to saved filters

Consolidate the per-filter actions in both the toolbar and the sidebar
saved filter lists into a single overflow menu, and add a rename
operation.

Renaming edits the name in place in the list rather than in a modal. A
modal is portalled to the document body, which the toolbar's saved filter
dropdown reads as a click outside itself, so the dropdown would close
behind it and the user would have to reopen it to carry on. Enter
confirms, escape or blur abandons.

Keeping that dropdown open takes some care, since it is asked to close by
three separate mechanisms. Choosing an operation forwards a nested menu's
select up through SelectableContext, and the operations menu is portalled
to the document body so it also reads as a click outside; the dropdown is
therefore controlled, and ignores a close while an operation is being
started. It uses a callback from the menu rather than inspecting the
event, because useRootClose evaluates containment in the capture phase,
before React has run its handlers, so by the time the close arrives the
clicked item may already be unmounted. Escape is the third: react-
overlays' Dropdown listens for it on keydown and useRootClose on keyup,
so the name input stops both and abandons the rename on keyup, while it
is still mounted to do so.

The filter is re-saved under its existing ID with the new name. Its
stored find_filter, object_filter and ui_options are passed through
untouched rather than round-tripped through ListFilterModel: a criterion
type the current UI doesn't recognise becomes an UnsupportedCriterion,
which neither reads itself in nor writes itself back, and saving replaces
object_filter wholesale - so a round-trip would silently delete such a
criterion. Legacy criteria like career_length and movies are affected.

Names are trimmed, and a rename onto an existing name is rejected before
saving rather than surfacing a raw uniqueness constraint error. As in
SaveFilterDialog the comparison is case-insensitive, even though the
unique index is not, to avoid a confusing "foo"/"Foo" pair. A rejected
rename leaves the name in the editor rather than discarding it.

The menu also allows an existing saved filter to be made the default for
the view. The toolbar menu's own Set as default button has been removed,
since having two controls with the same label in the one menu is
confusing and it did something different - it set the default from the
current filter rather than from a saved one. That remains available from
the sidebar, which is present on every view that has the toolbar.

OperationDropdown gains optional icon, id, title, size, toggle class and
onClick props so that the per-filter menu can reuse it instead of
duplicating it. All are defaulted, leaving existing callers unaffected.

Two components that were being declared during a render are no longer:
the dropdown's menu, and the toolbar's filter rows. Each was a new
component type on every render, remounting its subtree and discarding an
in-progress rename.

* Document the saved filter operations menu

Also mention that saved filters are available in the filter sidebar, not
just in the toolbar bookmark menu, and that the current filter is set as
the default from the sidebar.
2026-10-07 11:14:47 -07:00
.github Update CODEOWNERS 2026-08-05 17:34:38 +03:00
.idea Feature: Support Multiple URLs in Studios (#6223) 2025-11-10 14:34:21 +11:00
cmd fix: address clawpatch security and reliability findings (#6941) 2026-06-26 10:46:15 +10:00
docker feat: support TZ environment variable for timezone configuration (#7054) 2026-06-24 17:18:12 +10:00
docs Add credentials step to initial setup wizard (#7080) 2026-07-01 15:52:28 +10:00
graphql New: Add Scene Production Date field (#6533) 2026-09-01 17:24:37 -07:00
internal New: Add Scene Production Date field (#6533) 2026-09-01 17:24:37 -07:00
pkg Fix: Handle Long Log Lines From Scrapers and Plugins (#7171) 2026-09-01 19:43:54 -07:00
scripts Login page internationalisation (#5765) 2025-03-27 11:56:43 +11:00
ui New/RFC: Saved Filter List refactor (#7224) 2026-10-07 11:14:47 -07:00
.dockerignore Improve client-side graphql scalar types (#4511) 2024-02-07 09:49:32 +11:00
.gitattributes Refactor build (#493) 2020-04-29 12:13:08 +10:00
.gitignore Replace prettier/eslint with biome (#6996) 2026-06-04 14:27:53 +10:00
.golangci.yml Upgrade go to 1.25.9 and golangci-lint (#6869) 2026-04-29 10:13:58 +10:00
.gqlgenc.yml Upgrade gqlgenc (#5901) 2025-06-03 08:55:51 +10:00
.mockery.yml Model refactor (#3915) 2023-09-01 10:39:29 +10:00
go.mod Bump golang.org/x/crypto from 0.51.0 to 0.52.0 (#7110) 2026-07-23 10:26:51 +10:00
go.sum Bump golang.org/x/crypto from 0.51.0 to 0.52.0 (#7110) 2026-07-23 10:26:51 +10:00
gqlgen.yml FR: Change Career Length to Career Start and Career End (#6449) 2026-02-17 13:44:03 +11:00
LICENSE Add LICENSE until we get all signers on the switch (#297) 2020-01-20 22:18:12 -05:00
Makefile fix: address clawpatch security and reliability findings (#6941) 2026-06-26 10:46:15 +10:00
README.md Add AI usage policy, update contributing section (#6995) 2026-06-04 13:36:26 +10:00
tools.go Update go dependencies (#3480) 2023-02-28 08:26:14 +11:00

Stash

Build Docker pulls GitHub Sponsors Open Collective backers Go Report Card Discord GitHub release (latest by date) Codeberg Translate GitHub issues by-label

Stash is a self-hosted webapp written in Go which organizes and serves your diverse content collection, catering to both your SFW and NSFW needs.

Screenshot of Stash web application interface

  • Stash gathers information about videos in your collection from the internet, and is extensible through the use of community-built plugins for a large number of content producers and sites.
  • Stash supports a wide variety of both video and image formats.
  • You can tag videos and find them later.
  • Stash provides statistics about performers, tags, studios and more.

You can watch a SFW demo video to see it in action.

For further information see Support & Resources section.

Installing Stash

Tip

Step-by-step instructions are available at docs.stashapp.cc/installation.

Important

Windows Users

As of version 0.27.0, Stash no longer supports Windows 7, 8, Server 2008 and Server 2012.
At least Windows 10 or Server 2016 is required.

macOS Users

As of version 0.29.0, Stash requires macOS 11 Big Sur or later.
As of version 0.32.0, Stash requires macOS 12 Monterey or later.
Older versions can still be run through Docker.

Windows macOS Linux Docker
Latest Release
Development Preview
Latest Release
Development Preview
Latest Release (amd64)
Development Preview (amd64)
More Architectures...
Instructions
Sample docker-compose.yml

Download links for other platforms and architectures are available on the Releases page.

First Run

Windows/macOS Users: Security Prompt

On Windows or macOS, running the app might present a security prompt since the application binary isn't yet signed.

  • On Windows, bypass this by clicking "more info" and then the "run anyway" button.
  • On macOS, Control+Click the app, click "Open", and then "Open" again.

ffmpeg

Stash requires FFmpeg. If you don't have it installed, Stash will prompt you to download a copy during setup. It is recommended that Linux users install ffmpeg from their distro's package manager.

Usage

Quickstart Guide

Stash is a web-based application. Once the application is running, the interface is available (by default) from http://localhost:9999.

On first run, Stash will prompt you for some configuration options and media directories to index, called "Scanning" in Stash. After scanning, your media will be available for browsing, curating, editing, and tagging.

Stash can pull metadata (performers, tags, descriptions, studios, and more) directly from many sites through the use of scrapers, which integrate directly into Stash. Identifying an entire collection will typically require a mix of multiple sources:

  • The stashapp team maintains StashDB, a crowd-sourced repository of scene, studio, and performer information. Connecting it to Stash will allow you to automatically identify much of a typical media collection. It runs on our stash-box software and is primarily focused on mainstream digital scenes and studios. Instructions, invite codes, and more can be found in this guide to Accessing StashDB.
  • Several community-managed stash-box databases can also be connected to Stash in a similar manner. Each one serves a slightly different niche and follows their own methodology. A rundown of each stash-box, their differences, and the information you need to sign up can be found in the Metadata Sources section of the documentation.
  • Many community-maintained scrapers can also be downloaded, installed, and updated from within Stash, allowing you to pull data from a wide range of other websites and databases. They can be found by navigating to Settings → Metadata Providers → Available Scrapers → Community (stable). These can be trickier to use than a stash-box because every scraper works a little differently. For more information, please visit the CommunityScrapers repository.
  • All of the above methods of scraping data into Stash are also covered in more detail in our Guide to Scraping.

StashDB is the canonical instance of our open source metadata API, stash-box.

Support & Resources

Need help or want to get involved? Start with the documentation, then reach out to the community if you need further assistance.

Documentation

Community & Discussion

Community Scrapers & Plugins

Architecture

You can find an overview of Stash's architecture in the ARCHITECTURE.md document.

Contributing

We welcome contributions and help from all humans who want to improve the project.

Before contributing, please read the Contributing document to understand our guidelines and processes for contributing to the project.

You can learn about setting up a local development environment in the Development document.

Translation

The widget below shows the current translation status of Stash across all supported languages. If you want to help us translate Stash, you can make an account at Codeberg Translate to contribute to new or existing languages. Thanks!

Translation status