Folo Documentation

Folo is the AI RSS Reader

39,154 stars TypeScript TypeScript 20 files ยท ~125,494 tokens #ai#reader#rss#rss-reader#rsshub
RAW Doc

File: README.md

Folo is an open-source AI RSS reader that brings everything you follow into one calm timeline, then helps you read it. Follow blogs, news sites, newsletters, podcasts, video channels and social feeds in one place, ask AI about what you read, get a digest of your day, and let summaries and translations do the heavy lifting.

๐Ÿ‘‹๐Ÿป Getting Started & Join Our Community

Folo runs in the browser and on iOS, Android, macOS, Windows and Linux, and keeps your subscriptions, read status and stars in sync across all of them. It is under active development, and feedback is welcome for any issue you run into.

Platform Download
Web
iOS
Android
macOS
Windows
Linux

You can also install using the following methods maintained by our community:

Join our Discord server to connect with developers, request features, and receive support.
Follow us on X for product updates.

[!IMPORTANT]

Star Us, You will receive all release notifications from GitHub without any delay ~

โœจ Features

Folo AI

Ask about an article, a feed, a folder or everything you follow. Pick your AI model or bring your own API key, and connect MCP services to bring your other tools into Folo AI.

Timeline Summary

Turn hundreds of new entries into one quick digest of what matters.

AI Translation and Summaries

Read articles side by side with an AI translation in English, Chinese, Japanese or French, and get an AI summary of any article, on demand or automatically.

Every Format

Articles, social posts, pictures, videos and podcasts each get a layout made for them, and text-to-speech reads any article aloud with natural voices.

AI Tasks

Schedule AI tasks that write daily or weekly briefings and deliver them to chat or email.

Integrations

Send articles to Obsidian, Readwise, Instapaper, Zotero, Cubox, Outline, Readeck or Eagle, and let Actions filter, star, rewrite, notify or summarize new entries with your own rules.

On Your Phone

Folo for iPhone, iPad and Android brings AI summaries, read-aloud and discovery with you, and picks up where you left off on your computer.

And More

  • Subscribe to any RSS, Atom or JSON feed, plus thousands of RSSHub routes for sites without a feed
  • Import and export OPML to move from any other reader
  • An inbox with its own email address for newsletters
  • Customizable keyboard shortcuts and a command menu
  • Themes, reading fonts, custom CSS and code highlighting
  • Spotlight highlights the keywords you care about
  • Open source, with no ads

๐Ÿค Contributing

You are welcome to join the open source community to build together, please check our Contributing Guide for more details.

๐Ÿ” Code signing policy

Folo for Windows uses free code signing provided by SignPath.io, a certificate by SignPath Foundation.

Folo for macOS and iOS is signed and notarized by Apple Developer Program.

All released files are verified with GitHub artifact attestations to ensure their provenance and integrity.

๐Ÿ“ License

Folo is licensed under the GNU Affero General Public License version 3 with the addition of the following special exception:

All content in the icons/mgc directory is copyrighted by https://mgc.mingcute.com/ and cannot be redistributed.


File: AGENTS.md

AGENTS.md

This file provides concise, agent-focused guidance for working in this monorepo. It consolidates the repository's CLAUDE.md guides, .cursor rules, Cursor rules improvements, and modern agent best practices.

Project overview

  • Monorepo managed by pnpm workspaces + Turbo.
  • Apps:
    • apps/desktop โ€“ Electron app (Vite + React renderer is the primary web app)
    • apps/mobile โ€“ React Native app via Expo
    • apps/ssr โ€“ Minimal SSR site for external sharing
  • Shared packages: packages/internal (components, atoms, hooks, store, utils, database, etc.).

Setup commands

bash
# Install deps
pnpm install

# Desktop โ€“ recommended (browser renderer)
cd apps/desktop && pnpm run dev:web

# Desktop โ€“ full Electron
cd apps/desktop && pnpm run dev:electron

# Mobile โ€“ Expo
cd apps/mobile && pnpm run dev
# or target platforms
cd apps/mobile && pnpm run ios
cd apps/mobile && pnpm run android

# SSR
cd apps/ssr && pnpm run dev

# Build web version (desktop renderer)
pnpm run build:web

Quality gates (must-pass before commit/PR)

bash
# 1) Typecheck first (required)
pnpm run typecheck

# 2) Lint and auto-fix
pnpm run lint:fix

# 3) Tests
pnpm run test
  • Run the above at the root, or use per-package variants as needed.
  • Follow this order strictly: typecheck โ†’ lint โ†’ test.
  • After every modification, run the following checks to catch errors early:
bash
npm exec turbo run format:check typecheck lint
npm exec turbo run test

Code style and conventions

  • TypeScript strict; avoid any (use precise types). Comments in English. Keep solutions simple and maintainable.
  • Prefer CSS transitions/animations for simple UI interactions. Use JS-driven motion only when necessary to avoid frame drops.
  • Imports: use pathe instead of node:path for crossโ€‘platform paths.
  • Organize shared, reusable UI in packages/internal/components; app-specific UI stays in its app.
  • Style extraction: Avoid inline styles in JSX. Extract complex styles (especially those using CSS variables, gradients, or multiple properties) to external style objects similar to React Native's StyleSheet.create. Place style objects in a styles.ts file alongside the component, using CSSProperties type for type safety.

Team preferences

  • Prefer CSS transitions/animations over JS-based motion for simple interactions to avoid frame drops.
  • Prefer simple, easy-to-maintain solutions.
  • Avoid using the any type in TypeScript.
  • Write code comments in English.

Architecture quick reference

  • State: Jotai for atoms, Zustand for complex stores, TanStack Query for server state.
  • Database: Drizzle + SQLite (see packages/internal/database).
  • Error handling: custom utils in packages/internal/utils; Sentry integrated.
  • i18n: i18next with flat keys only; no defaultValue. Provide en, zh-CN, ja for each feature. Avoid conflicting dotted keys.

UI system and design tokens

Tailwind + Apple UIKit colors (Desktop/Web)

  • Use Tailwind classes bound to Apple UIKit color tokens (light/dark adaptive). Prefix by CSS property:
    • System colors: text-red, bg-blue, border-gray, etc. for red|orange|yellow|green|mint|teal|cyan|blue|indigo|purple|pink|brown|gray.
    • Fill: bg-fill[-secondary|-tertiary|-quaternary|-quinary] and bg-fill-vibrant[-secondary|-tertiary|-quaternary|-quinary] (and border-* as needed).
    • Text: text-text, text-text-secondary|tertiary|quaternary|quinary, text-text-vibrant(-secondary|-tertiary|-quaternary|-quinary).
    • Material: bg-material-ultra-thick|thick|medium|thin|ultra-thin|opaque.
    • Control: bg-control-enabled|disabled.
    • Interface: bg-menu|popover|titlebar|sidebar|selection-focused|selection-focused-fill|selection-unfocused|selection-unfocused-fill|header-view|tooltip|under-window-background.

These classes map to the UIKit color variables (see .cursor rules/color and apps/desktop/AGENTS.md).

Icons (Desktop/Web)

  • Prefer MingCute with i-mgc- prefix (e.g., i-mgc-copy-cute-re). Use i-mingcute- only if no i-mgc- exists.

Motion (Desktop/Web)

  • Use Framer Motion with LazyMotion via m from motion/react (e.g., m.div).
  • Prefer spring presets from @follow/components/constants/spring.js (Spring.presets.smooth|snappy|bouncy).
  • For simple micro-interactions, prefer CSS transitions first.

React Native (Mobile)

  • Styling: NativewindCSS; do not use external StyleSheet.create for new UI.
  • Icons: use @/apps/mobile/icons only.
  • Colors: use React Native UIKit color system (via react-native-uikit-colors) with Tailwind utilities:
    • Backgrounds: system-background, secondary-system-background, tertiary-system-background.
    • Grouped backgrounds: system-grouped-background, secondary-system-grouped-background, tertiary-system-grouped-background.
    • Labels: label, secondary-label, tertiary-label, quaternary-label.
    • Fills: system-fill, secondary-system-fill, tertiary-system-fill, quaternary-system-fill.
    • Separators: separator, opaque-separator, non-opaque-separator.
    • Semantic colors: red|orange|yellow|green|mint|teal|cyan|blue|indigo|purple|pink|brown, grays gray..gray6, and interactive link, placeholder-text.

Component placement

  1. Check existing components in apps/desktop/layer/renderer/src/modules/renderer/components for app-specific UI.
  2. If generic and reusable, implement in packages/internal/components and export from the package index.

Testing & CI tips

  • Use Vitest for unit tests; co-locate tests near source files.
  • After moving files or changing imports, run pnpm lint and pnpm typecheck for the affected package.
  • CI expects pnpm typecheck, pnpm lint, and pnpm test to pass before merge.

Agent workflow (Cursor-oriented improvements)

  • Status updates: provide brief progress notes when running tool batches.
  • Prefer semantic code search to explore unfamiliar areas; use exact grep only for symbols.
  • Default to parallelizing independent searches/reads to reduce latency.
  • Avoid multi-line speculative edits; keep edits minimal and targeted; preserve existing indentation.
  • When editing TypeScript, do not introduce any; keep types precise.
  • For UI, prefer CSS transitions for simple effects; use Framer Motion m.* only when needed.

Context7 (up-to-date docs)

  • Use Context7 to fetch current library docs before using APIs prone to change.
  • Workflow:
    1. Resolve a library ID: resolve the library (e.g., React Native, Vite, TanStack Query).
    2. Fetch docs scoped to the topic (e.g., hooks, routing).
    3. Integrate code examples following our style rules.

Sequential Thinking (step-by-step problem solving)

  • Break work into small thought steps:
    1. Define immediate goal/assumption.
    2. Use suitable tool (search, code edit, error explainer, docs).
    3. Record the output/results.
    4. Decide next step or branch alternatives; compare trade-offs.
  • Encourage rollback/iteration if new information contradicts prior steps.

Subproject guides

  • This root AGENTS.md sets global rules. Each app/package should include its own AGENTS.md (e.g., apps/desktop/AGENTS.md, apps/mobile/AGENTS.md). The closest guide to the edited file takes precedence when rules conflict.

Quick checklists

  • Implementation

    • Is code placed in the right package/app?
    • Type-safe (no any), readable names, English comments where needed.
    • Uses correct UIKit Tailwind tokens and icon sources.
    • For motion: CSS first; m.* only if necessary.
  • Validation

    • pnpm typecheck passes
    • pnpm lint:fix passes cleanly
    • Tests updated and pass

File: buildServer.json

{
"name": "xcode build server",
"version": "0.2",
"bspVersion": "2.0",
"languages": ["c", "cpp", "objective-c", "objective-cpp", "swift"],
"argv": ["/opt/homebrew/bin/xcode-build-server"],
"workspace": "/Users/innei/git/work/rss3/follow/apps/mobile/ios/Folo.xcworkspace",
"build_root": "/Users/innei/Library/Developer/Xcode/DerivedData/Folo-dtqltpwzjnyxzeeeuvortyjqrpno",
"scheme": "Folo",
"kind": "xcode"
}


File: CODE_OF_CONDUCT.md

Contributor Covenant Code of Conduct

Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

Our Standards

Examples of behavior that contributes to creating a positive environment
include:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints and experiences
  • Gracefully accepting constructive criticism
  • Focusing on what is best for the community
  • Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

  • The use of sexualized language or imagery and unwelcome sexual attention or
    advances
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or electronic
    address, without explicit permission
  • Other conduct which could reasonably be considered inappropriate in a
    professional setting

Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [email protected]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


File: conductor.json

{
"scripts": {
"setup": "pnpm i; cp $CONDUCTOR_ROOT_PATH/apps/desktop/.env.local apps/desktop/.env.local",
"run": "pnpm dev:web"
}
}


File: CONTRIBUTING.md

Contributing to Folo

Thank you for considering contributing to Folo! We welcome contributions from the community to help improve and expand the project.

Getting Started

Before you start contributing, please ensure you have enabled Corepack. Corepack ensures you are using the correct version of the package manager specified in the package.json.

sh
corepack enable && corepack prepare

Installing Dependencies

To install the necessary dependencies, run:

sh
pnpm install

Development Setup

Develop in the Browser

For a more convenient development experience, we recommend developing in the browser:

sh
cd apps/desktop && pnpm run dev:web

This will open the browser at https://app.folo.is/__debug_proxy, allowing you to access the online API environment for development and debugging.

Develop in Electron

If you prefer to develop in Electron, follow these steps:

  1. Go to the apps/desktop directory:

    sh
    cd apps/desktop
  2. Copy the example environment variables file:

    sh
    cp .env.example .env
  3. Set VITE_API_URL to https://api.follow.is in your .env file.

  4. Run the development server:

    sh
    pnpm run dev:electron

Tip: If you encounter login issues, copy the __Secure-better-auth.session_token from your browser's cookies into the app.

Develop in External SSR Web App

To develop in SSR, follow these steps:

  1. Go to the apps/ssr directory:

    sh
    cd apps/ssr
  2. Run the development server:

    sh
    pnpm run dev

Develop in Mobile App

To develop in the mobile app, follow these steps:

[!NOTE]
You need to have a Mac device to develop in the mobile app.

And already installed Xcode and the necessary dependencies.

  1. Go to the apps/mobile directory:

    sh
    cd apps/mobile
  2. Copy the example environment variables file:

    sh
    cp .env.example .env

    Then set the required environment variables in your .env file:

    sh
    echo 'EXPO_PUBLIC_APP_CHECK_DEBUG_TOKEN="xxx"' >> .env

    Or manually edit the .env file to add:

    text
    EXPO_PUBLIC_APP_CHECK_DEBUG_TOKEN="xxx"

    the value is any string.

  3. Build and install Folo(dev) app from source: (This step will take a while and only need to be done once)

    sh
    pnpm expo prebuild --clean # Optional
    pnpm run ios
  4. Run the development server:

    sh
    pnpm run dev

Development Native Modules

To develop native iOS modules, follow these steps:

  1. Go to the apps/mobile directory:

    sh
    cd apps/mobile/ios
  2. Open project in Xcode:

    sh
    open Folo.xcworkspace
  3. Open Pods in left sidebar and select FollowNative:

  4. Build and run the project.

Contribution Guidelines

  • Ensure your code follows the project's coding standards and conventions.
  • Write clear, concise commit messages.
  • Include relevant tests for your changes.
  • Update documentation as necessary.

Community

Join our community to discuss ideas, ask questions, and share your contributions:

We look forward to your contributions!

License

By contributing to Folo, you agree that your contributions will be licensed under the GNU Affero General Public License version 3, with the special exceptions noted in the README.md.


File: package.json

{
"name": "@follow/monorepo",
"type": "module",
"private": true,
"packageManager": "[email protected]",
"description": "Follow everything in one place",
"author": "Folo Team",
"license": "AGPL-3.0-only",
"homepage": "https://github.com/RSSNext",
"repository": {
"url": "https://github.com/RSSNext/follow",
"type": "git"
},
"scripts": {
"build:packages": "turbo run build --filter="./packages//*"",
"build:web": "turbo run Folo#build:web",
"dedupe:locales": "eslint --fix locales/
",
"depcheck": "npx depcheck --quiet",
"dev:web": "turbo run @follow/web#dev @follow/ssr#dev",
"format": "prettier --write .",
"format:check": "prettier --check .",
"icons:sync": "tsx scripts/svg-to-rn.ts && prettier --write apps/mobile/src/icons//*.tsx && eslint --fix apps/mobile/src/icons//.tsx",
"icons:update": "tsx scripts/update-icon.ts",
"lint": "pnpm run lint:tsl && eslint",
"lint:fix": "eslint --fix",
"lint:tsl": "tsslint --project apps/
/tsconfig.json",
"mitproxy": "bash scripts/run-proxy.sh",
"polyfill-optimize": "pnpx nolyfill install",
"postinstall": "node scripts/link-cf-build-tools.mjs && pnpm run build:packages",
"prepare": "simple-git-hooks && corepack prepare",
"reinstall": "rm -rf node_modules && rm -rf apps//node_modules && rm -rf packages//node_modules && pnpm install",
"test": "cross-env CI=1 pnpm --recursive run test",
"typecheck": "turbo typecheck"
},
"devDependencies": {
"@electron-toolkit/tsconfig": "2.0.0",
"@eslint/compat": "2.1.1",
"@stylistic/eslint-plugin": "5.10.0",
"@tsslint/cli": "3.1.4",
"@tsslint/compat-eslint": "3.1.4",
"@tsslint/config": "3.1.4",
"@types/node": "26.6.2",
"@types/react": "19.2.18",
"@types/react-dom": "19.2.7",
"@vercel/node": "12.0.1",
"cross-env": "10.1.0",
"eslint": "10.11.0",
"eslint-config-hyoban": "7.0.3",
"eslint-plugin-react-native": "5.0.0",
"fast-glob": "3.3.3",
"glob": "13.0.6",
"lint-staged": "17.5.1",
"prettier": "3.9.8",
"prettier-plugin-tailwindcss": "0.8.1",
"raw-body": "4.0.0",
"react": "19.2.8",
"react-dom": "19.2.8",
"rimraf": "6.1.3",
"simple-git-hooks": "2.14.0",
"svg-parser": "2.1.0",
"tar": "7.5.22",
"tsl": "1.0.30",
"tsx": "4.23.15",
"turbo": "2.11.2",
"typescript": "catalog:",
"vite": "7.3.6",
"vitest": "5.0.1"
},
"simple-git-hooks": {
"pre-commit": "pnpm exec lint-staged"
},
"lint-staged": {
"": [
"eslint --fix",
"prettier --ignore-unknown --write"
],
"apps/mobile/src/**/
": [
"bash scripts/increment-build-id.sh"
],
"locales/**/*.json": [
"npm run dedupe:locales",
"git add locales"
]
}
}