Skip to content
Restu-AverianPublic

About

Discover and watch Korean animation (Aeni) for free, with a curated, ad-free viewing experience

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Resaeni

A free, ad-free streaming and discovery platform dedicated to Korean animation - Aeni.

Live Application

About Resaeni

Resaeni is a focused catalogue and watch experience for Korean animation, also known as Aeni. Instead of becoming another broad anime index, the project is intentionally scoped around helping people discover, explore, choose an episode, and watch Korean animated titles in one place.

The product philosophy is simple: watching should stay clean and interruption-free. Resaeni does not intentionally place advertisements around common playback interactions such as play, pause, seeking forward, or rewinding.

Why This Project

Korean animation is harder to discover than mainstream Japanese anime, so Resaeni treats focus as a product decision. The app prioritizes a narrow catalogue, direct navigation, and a quiet viewing surface over extra social or engagement features.

Current flow:

Discover -> Explore -> Choose Episode -> Watch

Core Experience

  • Home discovery: featured Aeni and curated tonight picks from the Worker /api/home endpoint.
  • Aeni Library: searchable, filterable, paginated catalogue at /anime.
  • Aeni details: title metadata, synopsis, genres, status, episode count, episodes, characters, and voice actor data.
  • Streaming page: native HTML video playback with previous/next episode navigation and an episode list.
  • Info & Support: an About Resaeni page for product context, plus a Report an Issue form so visitors can flag problems directly from the site.
  • Responsive interface: desktop navigation plus a mobile bottom navigation and responsive layouts across catalogue, detail, and watch pages.
  • Loading and fallback states: skeleton screens, image placeholders, image error assets, empty states, and API error states.

Info & Support

The Info & Support area groups the project's informational and feedback surfaces:

Info & Support
├── About Resaeni      # /info/about - what the project is and why it exists
└── Report an Issue    # /info/report - report problems directly from the site

Report an Issue

Report an Issue lets visitors submit problems without leaving the app. The form collects:

  • Issue Type (required): Playback problem, Missing or incorrect episode, Incorrect Aeni information, Artwork or image problem, Audio or subtitle problem, or Other.
  • Aeni Title and Episode (both optional) for context.
  • Description (required, 10-1000 characters).
  • Optional image attachments: up to 3 images, maximum 10 MB per image, PNG/JPEG/WebP only.

The frontend validates input for fast feedback, and the Worker re-validates everything server-side - including checking that attachment bytes actually match their declared image type - before anything is persisted.

Engineering Highlights

  • Separate frontend and API packages: the React/Vite application lives at the repository root, while the Hono API is maintained as a separate worker/ package. This keeps UI code and edge API code independently runnable.
  • Cloudflare-oriented deployment: the frontend uses the Cloudflare Vite plugin and deploys built assets through Wrangler; the API runs as a Cloudflare Worker with its own Wrangler config.
  • Turso-backed data: Worker routes use @libsql/client to read anime metadata, episodes, episode links, characters, and voice actors from Turso/libSQL. Turso also stores issue reports and their attachment metadata.
  • Cloudflare R2 attachments: validated report images are uploaded through the Worker's R2 binding (REPORTS_BUCKET); no R2 credentials are exposed to the frontend. Attachment binaries live in R2 while their metadata lives in Turso.
  • Full-stack Report an Issue flow: React builds a multipart FormData, Axios posts it through a shared service to the Hono Worker, which validates, persists the report row to Turso, uploads attachments to R2, then records attachment metadata back in Turso.
  • Server-side validation: frontend checks exist for UX; the Worker independently enforces field lengths, allowed issue types, attachment count, size limits, MIME allowlisting, and file-signature verification.
  • Compensating cleanup across systems: there are no cross-system transactions between Turso and R2, so if a report insert or attachment upload fails partway through, the handler deletes any R2 objects it uploaded and removes the partially created report row, reducing orphaned data.
  • Route-focused API design: /api/home, /api/anime, /api/anime/:mal_id, /api/download, and /api/reports are split into route folders with handlers and utilities that match their domain.
  • Pragmatic data fetching: TanStack Query handles client-side request caching and retry behavior for reads, while mutations (such as report submission) use useMutation.
  • SEO as active maintenance: route-level meta tags, canonical URLs, Open Graph/Twitter metadata, og:site_name, JSON-LD helpers, sitemap generation from static plus API-fetched detail URLs, robots.txt generation, and build-time HTML prerendering. Utility routes such as /info/report are served noindex, follow while content pages stay indexable.

Tech Stack

Frontend

  • React 19
  • Vite
  • Chakra UI v3
  • React Router
  • TanStack Query
  • Axios
  • Lucide React

Backend

  • Cloudflare Workers
  • Hono
  • TypeScript
  • @libsql/client

Data and Storage

  • Turso/libSQL for catalogue data, issue reports, and attachment metadata
  • Cloudflare R2 for report image attachments (public delivery via reports.resaeni.cc)
  • Environment-configured video base URL with episode link paths returned by the API

Infrastructure and Quality

  • Wrangler
  • Cloudflare Vite plugin
  • ESLint
  • Prettier
  • Node test runner for SEO helper coverage
  • Vitest configured for Worker tests

Application Routes

/                                        Home
/anime                                   Aeni Library
/anime/:mal_id                           Aeni Details
/anime/:mal_id/episode/:episode_number   Watch
/info                                    Redirects to /info/about
/info/about                              About Resaeni
/info/report                             Report an Issue (noindex)

API Routes

GET   /health                  Service health check
GET   /api/home                Home discovery payload
GET   /api/anime               Paginated, filterable Aeni list
GET   /api/anime/:mal_id       Aeni details, episodes, characters
GET   /api/download            Download endpoint
POST  /api/reports             Create an issue report (multipart form data)

Report Flow

Report an Issue Form
        |
        v
POST /api/reports (multipart FormData)
        |
        v
Cloudflare Worker (validation)
     |        \
     v         v
  Turso     Cloudflare R2
  report     image
  + meta     attachments

The Worker validates all fields and attachments first, inserts the report row into Turso (issue_reports), uploads each accepted image to R2 under issue-reports/<report-id>/, and records each upload in issue_report_attachments. If any step fails, uploaded R2 objects and the partial report row are cleaned up before returning an error.

Local Development

Requires Node.js 24 or newer.

Install and run the frontend:

npm install
npm run dev

Install and run the API Worker:

cd worker
npm install
npm run dev

Frontend environment variables:

VITE_API_BASE_URL       # Backend API base URL
VITE_SITE_URL           # Canonical site URL used by SEO build scripts
VITE_BASE_VIDEO_URL     # Base URL for video playback sources
VITE_BASE_ASSETS_URL    # Base URL for image/artwork assets

Worker environment variables:

TURSO_DATABASE_URL      # Turso/libSQL database URL
TURSO_AUTH_TOKEN        # Turso auth token
REPORTS_BUCKET          # Cloudflare R2 binding (configured via wrangler.jsonc, not a secret)

Useful Scripts

Root application:

npm run dev
npm run build        # sitemap generation + Vite build + prerender
npm run test
npm run lint
npm run format:check
npm run deploy

Worker:

cd worker
npm run dev
npm run typecheck
npm test
npm run deploy

SEO & Search Readiness

Technical SEO is treated as ongoing product work rather than a finished checklist:

  • Route-specific titles, descriptions, robots directives, and canonical URLs via a shared Seo component.
  • Open Graph and Twitter Card metadata, including og:site_name and a dedicated social image.
  • JSON-LD structured data helpers for content pages.
  • Sitemap generation at build time, combining static routes with Aeni detail URLs fetched from the API.
  • robots.txt generation alongside the sitemap.
  • Build-time HTML prerendering so crawlers receive meaningful markup for SPA routes.

Content pages remain indexable while utility pages such as /info/report are intentionally served noindex, follow.

Active Maintenance

Resaeni is maintained as an evolving product rather than a finished demo. The codebase and dependencies are reviewed regularly, with dependency maintenance planned as part of a monthly maintenance cycle.

Catalogue freshness is currently a maintenance responsibility, not an automatic synchronization feature in this repository. If automated content updates are added later, they should be documented from the implementation rather than implied.

About

Discover and watch Korean animation (Aeni) for free, with a curated, ad-free viewing experience

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages