2023-04-18 14:36:25 +07:00
<div align="center">
2026-03-13 11:05:40 +07:00
<a href="http://localhost:3000/"><img width="500" src="resources/project/images/lustpress-node_1.png" alt="lustpress"></a>
2023-04-18 14:36:25 +07:00
2026-03-13 11:05:40 +07:00
<h4 align="center">RESTful and experimental API for PornHub and other R18 websites</h4>
2023-04-18 14:36:25 +07:00
<p align="center">
<a href="https://github.com/sinkaroid/lustpress/actions/workflows/playground.yml"><img src="https://github.com/sinkaroid/lustpress/workflows/Playground/badge.svg"></a>
<a href="https://codeclimate.com/github/sinkaroid/lustpress/maintainability"><img src="https://api.codeclimate.com/v1/badges/29a2be78f853f9e3a4a3/maintainability" /></a>
</p>
2026-05-14 05:36:33 +07:00
Lustpress was originally named Lust and Express (legacy name) and now runs on **Bun ** + **Elysia ** .
The motivation of this project is carry an actionable data related to pornhub and other r18 sites with gather, similar design pattern, endpoint bindings, and consistent structure in mind.
2023-04-18 14:36:25 +07:00
<a href="https://sinkaroid.github.io/lustpress">Playground</a> •
<a href="https://github.com/sinkaroid/lustpress/blob/master/CONTRIBUTING.md">Contributing</a> •
<a href="https://github.com/sinkaroid/lustpress/issues/new/choose">Report Issues</a>
</div>
---
2026-05-14 04:57:54 +07:00
<a href="http://localhost:3000/"><img align="right" src="resources/project/images/nun.png" width="320"></a>
2023-04-18 14:36:25 +07:00
- [Lustpress ](# )
- [The problem ](#the-problem )
- [The solution ](#the-solution )
- [Features ](#features )
2026-03-13 11:05:40 +07:00
- [Running tests ](#Running-tests )
2023-04-18 14:36:25 +07:00
- [Prerequisites ](#prerequisites )
- [Installation ](#installation )
- [Docker ](#docker )
- [Manual ](#manual )
2026-05-14 05:36:33 +07:00
- [Tests ](#tests )
2023-04-18 14:36:25 +07:00
- [Playground ](https://sinkaroid.github.io/lustpress )
- [Routing ](#playground )
- [Status response ](#status-response )
2026-05-14 05:36:33 +07:00
- [Ph Challenge Solver ](#pornhub-js-challenge-solver )
2023-04-18 14:36:25 +07:00
- [CLosing remarks ](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md )
- [Alternative links ](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md#alternative-links )
- [Pronunciation ](#Pronunciation )
- [Legal ](#legal )
2026-03-13 11:05:40 +07:00
- [Discontinued playground ](#frequently-asked-questions )
- [again, discontinued playground ](#frequently-asked-questions )
2023-04-18 14:36:25 +07:00
## The problem
2026-03-13 11:05:40 +07:00
Many developers consume r18 websites as a source of data when building web applications. However, most of these sites — such as pornhub, redtube, and others — do not provide official APIs or public resources that can be easily integrated into applications.
As a result, developers often need to implement their own scraping logic, build multiple abstractions, and manually maintain integrations for each site.
Lustpress aims to simplify this process by providing a unified interface for accessing data across multiple r18 sites. Instead of maintaining separate implementations, developers can rely on Lustpress to reduce complexity and development overhead.
The current state of the service is **free to use ** , meaning anonymous usage is allowed. No authentication is required, and **CORS is enabled ** to support browser-based applications.
2023-04-18 14:36:25 +07:00
## The solution
2026-03-13 11:05:40 +07:00
Don't make it long, make it short. All processed through single rest endpoint bindings
<a href="https://sinkaroid.github.io/lustpress"><img src="resources/project/images/coverage.png" width="800"></a>
2023-04-18 14:36:25 +07:00
## Features
2026-03-13 11:05:40 +07:00
- Aggregates data from multiple sites.
- Provides a consistent and structured response format across all sources.
- Extracted objects are normalized and reassembled to support extensibility.
- Unified interface supporting **get ** , **search ** , and **random ** methods.
- Planned support for optional **JWT authentication ** in future releases.
- Primarily based on pure scraping techniques (with limited exceptions where required).
## Running tests
Some tests may fail in CI environments because certain websites restrict or block automated requests originating from CI infrastructure and shared IP ranges, but trying to keep up
2023-04-18 14:36:25 +07:00
| Site | Status | Get | Search | Random | Related |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | ------ | ------ | ------- |
| `pornhub` | [](https://github.com/sinkaroid/lustpress/actions/workflows/pornhub.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `xnxx` | [](https://github.com/sinkaroid/lustpress/actions/workflows/xnxx.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `redtube` | [](https://github.com/sinkaroid/lustpress/actions/workflows/redtube.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `xvideos` | [](https://github.com/sinkaroid/lustpress/actions/workflows/xvideos.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `xhamster` | [](https://github.com/sinkaroid/lustpress/actions/workflows/xhamster.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `youporn` | [](https://github.com/sinkaroid/lustpress/actions/workflows/youporn.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
2026-03-13 11:05:40 +07:00
| `eporner` | [](https://github.com/sinkaroid/lustpress/actions/workflows/eporner.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
| `txxx` | [](https://github.com/sinkaroid/lustpress/actions/workflows/txxx.yml) | `Yes` | `Yes` | `Yes` | `Yes` |
2023-04-18 14:36:25 +07:00
## Prerequisites
<table>
2026-05-14 04:57:54 +07:00
<td><b>NOTE:</b> Bun 1.3.13 or higher</td>
2023-04-18 14:36:25 +07:00
</table>
To handle several requests from each website, You will also need [Redis ](https://redis.io/ ) for persistent caching, free tier is available on [Redis Labs ](https://redislabs.com/ ), You can also choose another adapters as we using [keyv ](https://github.com/jaredwray/keyv ) Key-value storage with support for multiple backends. When you choosing your own adapter, all data must be stored with `<Buffer>` type.
## Installation
Rename `.env.schema` to `.env` and fill the value with your own
```bash
# default port
PORT = 3000
# backend storage, default is redis, if not set it will consume memory storage
REDIS_URL = redis://default:somenicepassword@redis -666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337
# ttl expire cache (in X hour)
EXPIRE_CACHE = 1
# you must identify your origin, if not set it will use default
2026-05-14 05:36:33 +07:00
USER_AGENT = "lustpress/8.2.3-alpha Bun/1.3.13"
2023-04-18 14:36:25 +07:00
```
### Docker
docker pull ghcr.io/sinkaroid/lustpress:latest
docker run -p 3000:3000 -d ghcr.io/sinkaroid/lustpress:latest
2026-03-14 11:52:05 +07:00
### Docker (adjust your own)
2023-04-18 14:36:25 +07:00
```bash
docker run -d \
--name=lustpress \
2026-03-14 11:52:05 +07:00
-p 3028:3000 \
2023-04-18 14:36:25 +07:00
-e REDIS_URL='redis://default:somenicepassword@redis -666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337' \
-e EXPIRE_CACHE='1' \
2026-05-14 05:36:33 +07:00
-e USER_AGENT='lustpress/8.2.3-alpha Bun/1.3.13' \
2023-04-18 14:36:25 +07:00
ghcr.io/sinkaroid/lustpress:latest
```
### Manual
git clone https://github.com/sinkaroid/lustpress.git
- Install dependencies
2026-05-14 04:57:54 +07:00
- `bun install`
2023-04-18 14:36:25 +07:00
- Lustpress production
2026-05-14 04:57:54 +07:00
- `bun run start:prod`
2023-04-18 14:36:25 +07:00
- Lustpress testing and hot reload
2026-05-14 04:57:54 +07:00
- `bun run start:dev`
2023-04-18 14:36:25 +07:00
2026-05-14 05:36:33 +07:00
## Tests
2026-03-13 11:05:40 +07:00
Run the following commands to execute tests for each supported source:
```bash
# Check whether all supported sites are available for scraping
2026-05-14 04:57:54 +07:00
bun run test
2026-03-13 11:05:40 +07:00
# Check whether ph and (maybe the others do..) do Solving challenge in their website
2026-05-14 04:57:54 +07:00
bun run test:mock
2026-03-13 11:05:40 +07:00
# Run tests for individual sources
2026-05-14 04:57:54 +07:00
bun run test:pornhub
bun run test:xnxx
bun run test:redtube
bun run test:xvideos
bun run test:xhamster
bun run test:youporn
bun run test:eporner
bun run test:txxx
2026-03-13 11:05:40 +07:00
```
2023-04-18 14:36:25 +07:00
### Start the production server
2026-05-14 04:57:54 +07:00
`bun run start:prod`
2023-04-18 14:36:25 +07:00
### Running development server
2026-05-14 04:57:54 +07:00
`bun run start:dev`
2023-04-18 14:36:25 +07:00
2026-03-13 11:05:40 +07:00
### Generating playground like swagger from apidoc definition
2026-05-14 04:57:54 +07:00
`bun run build:apidoc`
2023-04-18 14:36:25 +07:00
2026-03-13 11:05:40 +07:00
> To running other tests, you can see object scripts in file `package.json` or modify the `lustpress.test.ts` according your needs
2023-04-18 14:36:25 +07:00
## Playground
https://sinkaroid.github.io/lustpress
- These `parameter?` : means is optional
- `/` : index page
### PornHub
The missing piece of pornhub.com - https://sinkaroid.github.io/lustpress/#api -pornhub
- `/pornhub` : pornhub api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , `?sort`
- **related**, takes parameters : `id`
- **random**
- <u>sort parameters on search</u>
- "mr", "mv", "tr", "lg"
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/pornhub/get?id=ph63c4e1dc48fe7
- http://localhost:3000/pornhub/search?key=milf&page=2&sort=mr
- http://localhost:3000/pornhub/related?id=ph63c4e1dc48fe7
- http://localhost:3000/pornhub/random
2023-04-18 14:36:25 +07:00
### Xnxx
The missing piece of xnxx.com - https://sinkaroid.github.io/lustpress/#api -xnxx
- `/xnxx` : xnxx api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , and TBD
- **related**, takes parameters : `id`
- **random**
- <u>sort parameters on search</u>
- TBD
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/xnxx/get?id=video-17vah71a/makima_y_denji
- http://localhost:3000/xnxx/search?key=bbc&page=2
- http://localhost:3000/xnxx/related?id=video-17vah71a/makima_y_denji
- http://localhost:3000/xnxx/random
2023-04-18 14:36:25 +07:00
### RedTube
The missing piece of redtube.com - https://sinkaroid.github.io/lustpress/#api -redtube
- `/redtube` : redtube api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , and TBD
- **related**, takes parameters : `id`
- **random**
- <u>sort parameters on search</u>
- TBD
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/redtube/get?id=42763661
- http://localhost:3000/redtube/search?key=asian&page=2
- http://localhost:3000/redtube/related?id=42763661
- http://localhost:3000/redtube/random
2023-04-18 14:36:25 +07:00
### Xvideos
The missing piece of xvideos.com - https://sinkaroid.github.io/lustpress/#api -xvideos
- `/xvideos` : xvideos api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , and TBD
- **related**, takes parameters : `id`
- **random**
- <u>sort parameters on search</u>
- TBD
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/xvideos/get?id=video73564387/cute_hentai_maid_with_pink_hair_fucking_uncensored_
- http://localhost:3000/xvideos/search?key=hentai&page=2
- http://localhost:3000/xvideos/related?id=video73564387/cute_hentai_maid_with_pink_hair_fucking_uncensored_
- http://localhost:3000/xvideos/random
2023-04-18 14:36:25 +07:00
### Xhamster
The missing piece of xhamster.com - https://sinkaroid.github.io/lustpress/#api -xhamster
- `/xhamster` : xhamster api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , and TBD
- **related**, takes parameters : `id`
- **random**
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/xhamster/get?id=videos/horny-makima-tests-new-toy-and-cums-intensely-xhAa5wx
- http://localhost:3000/xhamster/search?key=arab&page=2
- http://localhost:3000/xhamster/related?id=videos/horny-makima-tests-new-toy-and-cums-intensely-xhAa5wx
- http://localhost:3000/xhamster/random
2023-04-18 14:36:25 +07:00
### YouPorn
The missing piece of youporn.com - https://sinkaroid.github.io/lustpress/#api -youporn
- `/youporn` : youporn api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page` , and TBD
- **related**, takes parameters : `id`
- **random**
- <u>sort parameters on search</u>
- TBD
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/youporn/get?id=16621192/chainsaw-man-fuck-makima-3d-porn-60-fps
- http://localhost:3000/youporn/search?key=teen&page=2
- http://localhost:3000/youporn/related?id=16621192/chainsaw-man-fuck-makima-3d-porn-60-fps
- http://localhost:3000/youporn/random
### Eporner
https://sinkaroid.github.io/lustpress/#api -eporner
- `/eporner` : eporner api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page`
- **related**, takes parameters : `id`
2023-04-18 14:36:25 +07:00
- **random**
- <u>sort parameters on search</u>
- TBD
- Example
2026-03-13 11:05:40 +07:00
- http://localhost:3000/eporner/get?id=ibvqvezXzcs
- http://localhost:3000/eporner/search?key=makima&page=2
- http://localhost:3000/eporner/related?id=GPOFlSQLukS
- http://localhost:3000/eporner/random
### Txxx
https://sinkaroid.github.io/lustpress/#api -txxx
- `/txxx` : txxx api
- **get**, takes parameters : `id`
- **search**, takes parameters : `key` , `?page`
- **related**, takes parameters : `id`
- **random**
- Example
- http://localhost:3000/txxx/get?id=5309183
- http://localhost:3000/txxx/search?key=femboy&page=1
- http://localhost:3000/txxx/related?id=7794034
- http://localhost:3000/txxx/random
2023-04-18 14:36:25 +07:00
## Status response
`"success": true,` or `"success": false,`
HTTP/1.1 200 OK
HTTP/1.1 400 Bad Request
HTTP/1.1 500 Fail to get data
2026-05-14 04:57:54 +07:00
## Pornhub JS Challenge Solver
Pornhub serves a JavaScript challenge page to detect automated requests. Instead of relying on a headless browser (Playwright/Puppeteer), Lustpress solves this natively with zero external dependencies.
**How it works:**
- Fetch the index page and capture initial session cookies
- Detect the `leastFactor` math challenge in the response HTML
- Parse obfuscated variables (`p` , `s` ) and conditional bitwise operations
- Compute the correct `KEY` cookie value
- Verify the solved cookie against the index
- Cache and reuse cookies for subsequent requests, auto-refresh on expiry
This approach runs in * * < 1ms** compared to 5-10s with a headless browser, uses virtually no memory, and is fully **Docker-friendly ** — no Chromium installation required.
The solver logic lives in [`src/utils/ph-solver.ts` ](src/utils/ph-solver.ts ). If Pornhub changes its obfuscation pattern, update the regex patterns in that file.
2023-04-18 14:36:25 +07:00
## Frequently asked questions
**Q: The website response is slow**
2026-03-13 11:05:40 +07:00
> That's unfortunate, this repository was opensource already, You can host and deploy Lustpress with your own instance. Any fixes and improvements will updating to this repo.
> **March 11, 2026**:
We have discontinued providing public APIs and playground services due to ongoing abuse and excessive usage.
To continue using Lustpress, please deploy and run your own self-hosted instance.
2023-04-18 14:36:25 +07:00
## Pronunciation
`en_US` • * * /lʌstˈ prɛs/** — "lust" stand for this project and "press" for express.
## Legal
This tool can be freely copied, modified, altered, distributed without any attribution whatsoever. However, if you feel
like this tool deserves an attribution, mention it. It won't hurt anybody.
2026-05-14 04:57:54 +07:00
> Licence: WTF.