AvHub: a self-hosted R18 search front end with a FastAPI backend
R18 Resource Search & Management Tool
At a glance
- What is it?
- AvHub is a Vue 3 and FastAPI application that queries missav for magnet links by video code and archives hacg posts. It is a retrieval layer, not a media library, and its usefulness depends on a proxy and on sources you do not control.
- Who is it for?
- Adopt AvHub if you want a small, self-hosted front end that turns a video code into a magnet link and you already have a working path to missav, either directly or through the proxy_url setting in data/config.yaml. Do not adopt it if you need a media library, playback guarantees, or any resilience against source changes: the README states that no resource files are hosted and every result comes from a third-party link.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 167 days ago.
- What is it written in?
- Mainly Vue, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What AvHub actually solves for a self-hoster
The problem AvHub addresses is narrow and concrete: you have a video code and you want the corresponding magnet link and cover image without opening a browser and walking through a search page by hand. The README describes the first core feature as magnet link search by video code, with cover images returned alongside. Everything else in the application is built around that lookup.
The second job is archival. The README states that hacg resources are updated and archived monthly, with manual refresh available. That is a different kind of task from search: it is a scheduled crawl that writes results locally, and it is the reason the project ships a persistent data directory rather than running stateless.
The audience is therefore someone running a personal instance, most likely behind a proxy, who is comfortable with Docker and does not expect a polished consumer product. The interface supports Chinese and English, and the README lists five themes (Dark, Light, Emerald, Ocean, Amethyst). Those are interface details, not reasons to adopt it. The reason to adopt it is the lookup and the local archive.
One boundary is stated plainly in the README: AvHub does not host any resource files, and all data is retrieved through third-party links. That sentence defines what the project is. It is an index and a query layer over sources owned by other people.
How the Vue front end and FastAPI backend fit together
The architecture is a two-part application that ships as one process. The front end is Vue 3 with Vite, Tailwind CSS and hls.js. The backend is Python with FastAPI. The README says the front end is served directly by the FastAPI backend from web/dist, so there is no separate web server and no reverse proxy requirement in the default setup. The repository layout matches this: a web/ directory for the front end, main.py and utils/ for the backend, and a data/ directory for state.
The Dockerfile makes the build order explicit across two stages. The first stage uses node:20-slim, copies web/package*.json, runs npm ci, copies the rest of web/ and runs npm run build. The second stage uses python:3.13-slim, copies the repository into /app, copies the built assets from the first stage into /app/web/dist, and installs requirements.txt. That is why the README says no pre-build step is needed for the Docker path: the image builds the front end for you.
On the backend, requests to the sources go through a spider layer configured by av_spider in data/config.yaml. The dependency list includes aiohttp, curl_cffi, beautifulsoup4 and requests, which is consistent with a scraping layer rather than a formal API client. There is no database driver in requirements.txt. Persistence is filesystem-based: a cache directory defaulting to /app/data/.av, and a crawled video list at /data/video_urls.txt that feeds random recommendations.
That design has a consequence worth naming. There is no schema, no migration path and no query engine. If a source changes its markup, the spider returns nothing, and the application has no separate store to fall back on.
Installing AvHub with Docker and running a first search
The fastest path is the published image. The README gives this command, which maps port 8000 and mounts a local data directory so configuration and cache survive restarts.
docker run -d \
-p 8000:8000 \
-v $PWD/data:/app/data \
--name avhub \
levywang/avhub:latestAfter the container starts, the service answers at http://127.0.0.1:8000/. The README notes that the front end is served by the backend, so there is no second port to open.
If you prefer to build from source, the README gives the same two-stage result locally.
git clone https://github.com/levywang/avhub.git
cd avhub
docker build -t avhub .
docker run -d -p 8000:8000 -v $PWD/data:/app/data --name avhub avhubFor a host where missav is blocked, the proxy is the first thing to set. The README marks it as required for servers in China and shows the config block in data/config.yaml with source_url, proxy_url and use_proxy. The same settings can be passed as environment variables at container start.
docker run -d \
-p 8000:8000 \
-v $PWD/data:/app/data \
-e AUTH_ENABLED=true \
-e API_KEY=your-secret-key \
-e USE_PROXY=true \
-e PROXY_URL=http://192.168.50.3:7890 \
--name avhub \
levywang/avhub:latestWith that running, open the page and search a video code. The expected result is a magnet link and a cover image. If the page loads but searches return nothing, the proxy is the first suspect, not the front end. Note the default API_KEY value of 123456 in the environment table: if you enable authentication and leave that value, you have not protected anything.
The source dependency is the real failure mode
AvHub queries missav for magnet links and covers, and hacg liuli for hacg resources. Both are third-party sites. The README does not describe a fallback source, a mirror list, or an offline index. If missav changes its URL structure or blocks the request pattern, search stops working and the only fix is a code change in the spider layer. That is the honest limitation of the project, and it is not a bug that will be patched away, because the dependency is architectural.
The proxy requirement compounds this. The README states that missav is blocked in China and that a proxy is required for servers there. A misconfigured proxy_url, or a proxy that accepts HTTP but not SOCKS5, produces the same symptom as a broken source: an empty result set. There is no documented health check or status endpoint that distinguishes the two, so debugging means reading logs or testing the source URL separately.
Caching is on by default, with USE_CACHE set to true and CACHE_DIR pointing at /app/data/.av. That helps with repeat searches and does nothing for a cold query against a changed source. It also means stale results can be returned without an obvious signal, and the README does not document a cache invalidation command.
Finally, the legal disclaimer puts compliance on the user: the README says users must comply with the laws of their region. That is not a technical limitation, but it is a real constraint on where and how this can be deployed.
AvHub compared with a general media server
The closest thing to an alternative is a media server such as Jellyfin or Plex, and the difference is in what each one stores. A media server owns a library: you point it at files, it indexes them, it tracks watched state, and it serves playback. AvHub owns no files. The README is explicit that it does not host any resource files and that all data comes from third-party links. What it stores locally is a cache of search results and a crawled list of video URLs used for random recommendations.
That difference decides the use case. If you already have files and want to browse and play them, a media server is the right tool and AvHub adds nothing. If you have a code and want a link, AvHub is the smaller and more direct answer, and a media server will not help because there is nothing in its library to match.
The two can coexist without overlap: AvHub for discovery, a media server for playback once a file exists. The README does not describe any integration between them, so any such setup is manual. The hls.js dependency in the front end suggests streaming playback of some kind is part of the interface, but the README does not document what it plays or where the stream comes from, so treat that as unverified.
Maintenance, upgrades and the Apache-2.0 licence
The repository is not archived, and the last push was on 2026-04-18. The most recent release listed is v1.0.3 from 2025-04-16, following v1.0.2 in March 2025 and v1.0.1 in March 2025. The gap between the last release and the last push means the code has moved since the tagged version, so pinning to v1.0.3 and tracking main are not the same thing. The README does not document an upgrade procedure, a migration path for data/config.yaml, or what happens to the cache directory across versions.
Upgrade cost is low in one sense: the deployment is a container and a mounted data directory, so replacing the image is the whole operation. It is uncertain in another: because the spider targets live third-party sites, a working deployment can stop working without any change on your side. Budget for the possibility that an upgrade is needed to fix a source change rather than to gain a feature.
The licence is Apache-2.0, per the README and the LICENSE file. That is a permissive licence with an explicit patent grant and a requirement to preserve notices. It says nothing about the content the application indexes, and the README's disclaimer places that responsibility on the user. This is a description of the licence text, not legal advice; if you plan to redistribute a modified version, read the LICENSE file and the disclaimer in the README yourself.
Editorial conclusion
Adopt AvHub if you want a small, self-hosted front end that turns a video code into a magnet link and you already have a working path to missav, either directly or through the proxy_url setting in data/config.yaml. Do not adopt it if you need a media library, playback guarantees, or any resilience against source changes: the README states that no resource files are hosted and every result comes from a third-party link. Before committing, verify three things on your own host: that the image starts and answers on port 8000, that a search returns a magnet link with your proxy settings, and that the files under /app/data survive a container restart. If the proxy step fails, nothing else in the application matters.
Frequently asked questions
What port does AvHub listen on by default?
Port 8000. The README's Docker examples map 8000:8000 and the Dockerfile ends with EXPOSE 8000, and the README states the service is available at http://127.0.0.1:8000/.
Does AvHub store or host any video files?
No. The README states that AvHub does not host any resource files and that all data is retrieved via third-party links. What it keeps locally is a search cache under CACHE_DIR and a crawled list at /data/video_urls.txt used for random recommendations.
Why do searches return nothing after I start AvHub?
The most likely cause is the source connection rather than the front end. The README states that missav is blocked in China and that a proxy is required there, configured through proxy_url and use_proxy in data/config.yaml or through the USE_PROXY and PROXY_URL environment variables.
How do I protect an AvHub instance with an API key?
Set auth_enabled to true and api_key in the app section of data/config.yaml, or pass AUTH_ENABLED and API_KEY as environment variables. The environment table lists 123456 as the default API_KEY, so change it if you enable authentication.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/levywang-avhub)