A lightweight local viewer for browsing Sora manifest exports together with local mp4 and txt files.
This project assumes the data structure produced by SoraVault 2.0, including soravault_manifest_*.json files such as soravault_manifest_merged_*.json and the sora_v2_* export directory layout. This repository does not include or reuse SoraVault source code. It only works with the data structure generated by SoraVault 2.0 exports.
- Merges all
soravault_manifest_*.jsonfiles found insora2_data/ - Matches manifest items with local files from SoraVault 2.0 export directories
- Plays local videos inline in a dark gallery UI with a right-side details panel
- Searches by prompt,
genId,postId,taskId, TXT content, and date range with auto-apply filtering - Supports pagination, page size selection, source filtering, and sorting by date, prompt, duration, views, likes, and source order
- Supports keyboard browsing across gallery cards with
Tab,Enter,Space, and arrow keys - Shows manifest-derived metadata such as
posted by, likes, views, loaded manifest names, and TXT content
For release notes and change summaries, see CHANGELOG.md.
The summary strip at the top of the viewer uses these meanings:
Library: total indexed items across both manifest-backed entries andlocal-onlyentriesPlayback: items that have a localmp4file and can play inside the viewerText: items that have a localtxtsidecar fileManifest Gap:local-onlyitems found on disk that could not be matched back to manifest metadataSources: the number of unique indexed source buckets such asprofile,liked,drafts, user sources, and char sourcesxx-yy of nnnn items: the current page range inside the filtered result set
Requirements:
- Node.js 22.13+
- Verified in practice with Node.js 24
Windows (PowerShell):
git clone https://github.com/tinatsu-nomy/sora2-vault-viewer.git
cd sora2-vault-viewer
mkdir sora2_dataProject structure:
app/
public/
index.html
app.js
styles.css
server.js
sora2_data/
soravault_manifest_*.json
sora_v2_*/
Download your Sora2 export data into sora2_data/ so the layout looks like this:
sora2_data/
soravault_manifest_*.json
sora_v2_*/
Then start the viewer:
npm startThe app starts at http://localhost:3210 by default and automatically moves to the next free port if needed. To stop the server, return to the terminal where it is running and press Ctrl+C.
Electron desktop app:
npm install
npm run start:electronPortable Windows build:
npm install
npm run build:electronThe Electron app embeds the existing local HTTP viewer and opens it in a desktop window.
Portable build notes:
- Place
sora2_data/in the same parent folder as the generated executable, or setSORA_DATA_DIRexplicitly before launch - Recommended portable layout:
AnyFolder/
Sora2_Vault_Viewer-portable.exe
sora2_data/
soravault_manifest_*.json
sora_v2_*/
- For
electron-builderportable builds, the app prefersPORTABLE_EXECUTABLE_DIR\sora2_data\ - Electron stores settings in
app.getPath("userData")\app-data\viewer-config.json - If
SORA_DATA_DIRis not set, Electron first uses thedataDirvalue from that settings file - If no saved
dataDirexists yet, Electron falls back toSora2_Vault_Viewer-portable.exe's siblingsora2_data\ - If you move only the EXE to a different folder after first launch, the app may continue using the previously saved
dataDir - If the app does not read the
sora2_data\next to the EXE that you expect, setSORA_DATA_DIRexplicitly or updateviewer-config.json - If you change the data directory after the app has already been launched, initialize
app-data\as well so the saveddataDirand caches do not keep pointing at the previous location - Startup now prefers the last completed SQLite cache so the viewer opens faster on large libraries
- After adding or changing manifests, videos, or TXT files while the app is closed, click
Rescanto rebuild the cache from disk
Distribution:
- Release page: v0.2.6.3 release
- Portable download: Sora2_Vault_Viewer-portable.exe
- Place
sora2_data/in the same folder asSora2_Vault_Viewer-portable.exebefore launch - The app stores settings, SQLite cache, and TXT cache under
app.getPath("userData")\app-data\ - On Windows, this is typically
C:\Users\<your-user-name>\AppData\Roaming\Sora2 Vault Viewer\app-data\ - The Electron settings file is
app.getPath("userData")\app-data\viewer-config.json - On Windows, this is typically
C:\Users\<your-user-name>\AppData\Roaming\Sora2 Vault Viewer\app-data\viewer-config.json - If
viewer-config.jsoncontainsdataDir, Electron uses that path before checking the EXE's siblingsora2_data\whenSORA_DATA_DIRis not set PORTis not stored inviewer-config.json; the default HTTP port is3210and can be overridden with thePORTenvironment variable- Example
viewer-config.json:
{
"dataDir": "D:\\SoraExports\\sora2_data"
}- Example settings screen for configuring the data directory:
- Windows may show SmartScreen or other security prompts for unsigned executables
Uninstalling the portable Windows app:
- The portable build does not install itself into
Program Filesand does not add a standard Windows uninstaller - To remove the app itself, close it and delete
Sora2_Vault_Viewer-portable.exe - To remove your exported data from the same portable folder, also delete the adjacent
sora2_data/folder if you no longer need it - To remove saved settings and caches, delete
app.getPath("userData")\app-data\ - On Windows, this is typically
C:\Users\<your-user-name>\AppData\Roaming\Sora2 Vault Viewer\app-data\ - Deleting
app-data\removesviewer-config.json, the SQLite cache, and the TXT cache - If you want to keep your export data but reset the app state, delete only
app-data\and keepsora2_data/
Optional environment variables:
PORT: starting port for the local server. Defaults to3210SORA_BIND_HOST: bind host for the HTTP server. Defaults to127.0.0.1SORA_DATA_DIR: override the data directory locationSORA_VIEWER_ROOT: override the repository root whensora2_data/lives directly under a different parent directorySORA_APP_DATA_DIR: override the directory used for SQLite, TXT cache, and the Electron settings fileSORA_ENABLE_SQLITE_CACHE: defaults to enabled. Set0to disable the local SQLite cacheSORA_SQLITE_PATH: override the SQLite database file pathSORA_SQLITE_RENEW_ON_START: set1to delete the cached SQLite database before startup and force a full rebuild from manifests and local files
Common examples:
# default
npm start# disable the SQLite cache
$ENV:SORA_ENABLE_SQLITE_CACHE = "0"
npm start# custom data directory
$ENV:SORA_DATA_DIR = "D:\SoraExports\sora2_data"
npm start# force a fresh SQLite rebuild on startup
$ENV:SORA_SQLITE_RENEW_ON_START = "1"
npm start# custom port
$ENV:PORT = "3211"
$ENV:SORA_DATA_DIR = "D:\SoraExports\sora2_data"
npm startAdd new manifest JSON files:
- Copy the new
soravault_manifest_*.jsonfile intosora2_data/ - Keep the
soravault_manifest_*.jsonnaming pattern so the viewer can detect it automatically Examples includesoravault_manifest_2026-04-17.jsonandsoravault_manifest_merged_*.json - Click
Rescan - Confirm the file name appears in
Loaded manifests
Add new local media and TXT files:
- Put exported files into the matching source directory:
- Example:
sora_v2_profile - Example:
sora_v2_liked - Example:
sora_v2_drafts - Other SoraVault 2.0
sora_v2_*source directories are also supported
- Example:
- Keep each
mp4andtxtpair together using the exported file names from SoraVault 2.0 - Click
Rescan - Confirm the new items appear in the gallery and detail view
How local files are linked to manifest JSON:
- The files must be placed in the matching source directory for that export type
- The
mp4andtxtfiles must share the same stem - The viewer must be able to match the local files to a manifest item using one or more identifiers such as
generationId,taskId,postId, extracted ID tokens, or the file stem
In practice, a SoraVault 2.0 filename template such as {date}_{genId} has been confirmed to work with this viewer.
If these conditions are not met, the files can still appear as local-only items, but they will not be linked to manifest JSON metadata.
- If new manifests or files do not appear, click
Rescanand then checkLoaded manifests - On large libraries, startup may show cached results from the last completed scan until you click
Rescan - Use the
Renew next startcheckbox when you want the next app launch to behave likeSORA_SQLITE_RENEW_ON_START=1once and then return to normal cached startup behavior - If a manifest is malformed, the viewer skips it and continues indexing the remaining files
- If the UI shows an index, detail, or rebuild error, fix the underlying file issue and try
Rescanagain - Run
npm run checkfor syntax validation andnpm testfor the smoke test fixture Local onlyis enabled by default, so the initial feed focuses on files that exist locally- The server binds to loopback (
127.0.0.1) by default, so it stays local-only unless you explicitly overrideSORA_BIND_HOST - The
/mediaendpoint serves only indexed localmp4andtxtfiles - Sora 1 data is not supported
- Local media, manifests, caches, and backup logs are intentionally excluded by
.gitignore - This repository is provided as-is, without warranty or guarantee of compatibility, correctness, completeness, or fitness for a particular purpose
- Behavior is intended for SoraVault 2.0 export layouts and is not guaranteed for other export formats or future versions
MIT

