Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
93b361f
fix(sentry): stop reporting expected notFound/redirect as errors
sentry[bot] Sep 30, 2026
690b64e
docs: add Intent 0.5 release blog post (#1309)
LadyBluenotes Sep 30, 2026
8255887
fix(examples): Restore playground devtools and external editors (#1312)
KevinVandy Sep 30, 2026
c8755b6
docs: publish TanStack Start security update (#1314)
tannerlinsley Sep 30, 2026
5b24586
chore: update TanStack Start packages (#1315)
tannerlinsley Sep 30, 2026
126c59d
fix(builder): keep generated apps on current releases (#1317)
tannerlinsley Sep 30, 2026
4b573ae
Keep tab borders without left-edge fade (#1319)
LadyBluenotes Sep 30, 2026
3e188b4
Add Scarf Bronze partnership and announcement, archive Electric (#1318)
tannerlinsley Sep 30, 2026
d653e76
Clarify Markdown and Highlight landing pages (#1322)
tannerlinsley Oct 1, 2026
fabc018
Launch invite-only TanChat with canonical conversation URLs (#1326)
tannerlinsley Oct 2, 2026
e3a9ca3
Improve TanChat’s access page and add a waitlist (#1328)
tannerlinsley Oct 2, 2026
ff03f2b
Make TanChat navigation immediate and reuse conversation reads (#1329)
tannerlinsley Oct 2, 2026
a31798d
Fix admin freezing and add TanChat access management (#1330)
tannerlinsley Oct 2, 2026
bc69c6b
Hide the duplicate Assistant conversation entry (#1331)
tannerlinsley Oct 2, 2026
54a89fa
Show sending status during normal message submissions (#1332)
tannerlinsley Oct 2, 2026
1eacd17
Fix TanChat memory retention and message submission delays (#1333)
tannerlinsley Oct 3, 2026
a0d6ed6
Make local development work without service credentials (#1334)
tannerlinsley Oct 3, 2026
918322c
Fix session secret initialization during Worker startup (#1337)
tannerlinsley Oct 3, 2026
0113dd2
feat(hotkeys): add Alpine, Ember, and Octane framework support (#1340)
KevinVandy Oct 4, 2026
fdee6cc
perf(chat): render sends immediately and reduce response latency (#1339)
tannerlinsley Oct 4, 2026
5085d7f
perf(chat): reduce preparation latency and use Hyperdrive (#1343)
tannerlinsley Oct 5, 2026
01bcb35
perf(chat): unblock response delivery and measure send phases (#1344)
tannerlinsley Oct 5, 2026
aefe4a1
perf(chat): remove quota and admission round trips (#1345)
tannerlinsley Oct 5, 2026
694462f
feat(pacer): Add missing framework options (#1346)
KevinVandy Oct 5, 2026
1ecd496
fix: preserve route context during hydration recovery (#1341)
tannerlinsley Oct 5, 2026
07d48dd
fix(partners): refresh CodeRabbit light and dark branding (#1347)
tannerlinsley Oct 5, 2026
d119c8f
fix(DocFeedbackProvider): keep the feedback button below the docs tab…
sukvvon Oct 5, 2026
f7c6ea7
Launch TanStack Charts 1.0 (#1348)
tannerlinsley Oct 5, 2026
1f72920
fix(chat): keep transcript stable when sending (#1349)
tannerlinsley Oct 5, 2026
05ed0d5
Fix Charts bundle size comparison order (#1350)
tannerlinsley Oct 5, 2026
a9aa0ca
Replace Kapa with TanStack AI and Algolia Agent Studio (#1184)
dylantientcheu Oct 6, 2026
854c81a
Add layered interactive dot cloud to Charts hero (#1352)
tannerlinsley Oct 6, 2026
e36d5f3
Remove stale prerelease labels and verify v1 library pickers (#1321)
tannerlinsley Oct 6, 2026
862ccc3
Fix Charts text backdrop on Safari (#1355)
tannerlinsley Oct 6, 2026
cf61255
Redirect HTTP requests and use current docs cache bindings (#1358)
tannerlinsley Oct 10, 2026
0ee6d54
Pass Start compat config to Vite without pnpm's `--` (#1359)
Sheraff Oct 10, 2026
8d46e5d
chore(maintainers): add 'pacer' to the 'sukvvon' entry (#1361)
sukvvon Oct 11, 2026
72f3b4e
fix(scarf): guard crypto.randomUUID for non-secure contexts (#1360)
sentry[bot] Oct 12, 2026
c106598
fix: Prevent trailing slash in example paths (#1197)
sentry[bot] Oct 12, 2026
8cd95cd
fix(landing): square the bordered edge on accent callouts (#1206)
Abeuty Oct 12, 2026
ef4bb73
Draft TanStack Start 1.0 announcement (#1366)
tannerlinsley Oct 12, 2026
27ef3cc
Update Start 1.0 draft credits and partner contributions (#1368)
tannerlinsley Oct 12, 2026
fbdd516
Update Start 1.0 announcement with partner feedback (#1369)
tannerlinsley Oct 13, 2026
2ef5881
Add Start launch video and polish blog headers (#1370)
tannerlinsley Oct 13, 2026
1db04ca
Publish TanStack Start 1.0 stable announcement (#1371)
tannerlinsley Oct 13, 2026
9c4c881
fix(blog): restore composite components URL (#1367)
tannerlinsley Oct 13, 2026
8723dec
Remove TanStack Start release candidate labels (#1372)
tannerlinsley Oct 13, 2026
5c9a93f
Update TanStack Start version picker to v1 (#1373)
tannerlinsley Oct 13, 2026
7c96ea3
fix: hide unavailable library Discussions links (#1374)
tannerlinsley Oct 13, 2026
de92ae2
fix: preserve blog section headings and code comments (#1375)
tannerlinsley Oct 13, 2026
c0d2195
docs(db): fix broken code examples in release posts (#1376)
KyleAMathews Oct 13, 2026
6cfb65b
Fix local docs directory reads in worker previews (#1263)
tannerlinsley Oct 13, 2026
7c8e530
Canonicalize Markdown docs to HTML and return real 404s (#1265)
tannerlinsley Oct 13, 2026
d30aa71
fix(charts): return notFound for invalid catalog collection IDs (#1377)
sentry[bot] Oct 13, 2026
1ec8b82
fix: Allow bracket characters in repo path validation (#1238)
sentry[bot] Oct 14, 2026
3c6e2b5
fix: recognize Router control flow in Sentry filters
tannerlinsley Oct 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions .agents/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,22 @@ Inspired by https://github.com/DietrichGebert/ponytail
- [UI Style Guide](./ui-style.md): Visual design principles for 2026
- [Workflow](./workflow.md): Build commands, debugging, Playwright
- [Analytics](./analytics.md): GA4 event taxonomy, funnel definition, custom dimensions

## Writing and documentation

Use `tanner-writing-style` for public front-page headings and marketing copy,
and `editorial-restraint` for clarity and grounded claims, when those skills
are available. Front-page copy should be personable, punchy, and informal.
Lead with the benefit and preserve supplied sales emphasis while polishing
awkward phrasing. Concrete grounding does not require API names in every
headline or subhead; examples and linked documentation can carry that detail.

Keep API references and technical guides precise and approachable. Preserve
identifiers and explain actual behavior and relevant limitations without
imposing the marketing voice on reference documentation.

Read relevant implementation, contracts, and examples before changing product
claims. Keep capabilities, measurements, guarantees, and comparisons accurate.
If a consequential claim is unsupported, offer a stronger accurate alternative
briefly and continue within the requested scope. Subjective praise and useful
promotional hooks do not need to become dry technical prose.
35 changes: 35 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,38 @@ jobs:
run: pnpm build
- name: Run Tests
run: pnpm test

chat-runtime:
name: Chat PostgreSQL runtime
runs-on: ubuntu-latest
services:
postgres:
image: postgres:17
env:
POSTGRES_USER: tanchat_test
POSTGRES_PASSWORD: tanchat_test
POSTGRES_DB: tanchat_test_ci
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U tanchat_test -d tanchat_test_ci"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
DATABASE_URL: postgresql://tanchat_test:tanchat_test@127.0.0.1:5432/tanchat_test_ci
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Tools
uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main
- name: Create existing-site test boundary
run: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f harness-tests/postgres/site-baseline.sql
- name: Migrate disposable database
run: pnpm db:migrate
- name: Check cascade lifecycle
run: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f harness-tests/postgres/cascade-lifecycle.sql
- name: Run conversation runtime tests
run: pnpm test:chat-runtime
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ test-results
src/routeTree.gen.ts
.og-preview/
.readme-preview/

# Generated native desktop helper
/desktop/native/folder-access
20 changes: 20 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@
"react/exhaustive-deps": "warn"
},
"plugins": ["react", "jsx-a11y"]
},
{
"files": ["desktop/preload.cjs"],
"rules": {
"typescript/no-require-imports": "off"
}
},
{
"files": ["**/SavedFiles.tsx"],
"plugins": ["react", "jsx-a11y"],
"rules": {
"jsx-a11y/no-noninteractive-tabindex": [
"error",
{
"tags": [],
"roles": ["tabpanel", "region"],
"allowExpressionValues": true
}
]
}
}
]
}
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,37 @@ pnpm install
pnpm dev
```

This starts your app in development mode, rebuilding assets on file changes.
Requires Node.js 22.12 or newer and pnpm 11. This starts the site at http://localhost:3000 and rebuilds on file changes. No environment file, Cloudflare account, database, or sibling repository is required. Internet access is needed to download dependencies and read remote documentation.

### Optional services

Add only the credentials you need to `.env.local`, then restart `pnpm dev`. Environment files are read from this checkout, never from another checkout. Missing credentials disable the relevant local service, they do not prevent the site from starting.

| Service | Optional configuration | Without it |
| ------------------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Public docs | Sibling repositories or `TANSTACK_LOCAL_REPOS_DIR` | Reads public docs from GitHub. Local files take precedence. `TANSTACK_DOCS_USE_REMOTE=true` skips local files. |
| GitHub data | `GITHUB_AUTH_TOKEN` | Public REST and raw-file requests remain anonymous, with GitHub's rate limits. Private sponsor data is omitted. |
| Database features | `DATABASE_URL`, with the repository migrations applied | Showcase and Intent registry lists, plus the feedback leaderboard, are empty. Accounts and writes are unavailable. |
| GitHub sign-in | Database plus `GITHUB_OAUTH_CLIENT_ID` and `GITHUB_OAUTH_CLIENT_SECRET` | GitHub sign-in is hidden. |
| Google sign-in | Database plus `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` | Google sign-in is hidden. |
| Persistent sessions | `SESSION_SECRET` | Development generates a random worker-local secret. Restarting or reloading the worker signs you out. Production requires a configured secret. |
| Shopify | `SHOPIFY_PRIVATE_STOREFRONT_TOKEN` | The shop shows an unconfigured state with a link to the live shop. |
| Workers AI | `CLOUDFLARE_API_TOKEN`, plus `CLOUDFLARE_ACCOUNT_ID` to use your own account | Remote bindings are disabled. The included chat model is unavailable. Local R2, Durable Objects, and Workflows still use the local emulator. |
| TanChat and connected accounts | Database, sign-in, chat access, and `ENCRYPTION_KEY` of at least 32 characters | Private chat and encrypted connected-account storage are unavailable. Provider API keys can be added in chat settings once chat is configured. |
| AI Gateway | `AI_GATEWAY_ACCOUNT_ID`, `AI_GATEWAY_ID`, `AI_GATEWAY_TOKEN` | Configured providers connect directly. |
| Kody | `KODY_ORIGIN` and `ENCRYPTION_KEY`, then connect an account | Kody actions require a connected account. |
| Notifications | `DISCORD_WEBHOOK_URL` and/or `RESEND_API_KEY` | The corresponding notification transport is disabled. |
| Server error reporting | `SENTRY_DSN` | Local error reporting is disabled. Browser reporting and analytics only run in production. |
| Kapa docs assistant | `VITE_KAPA_INTEGRATION_ID` and optional `VITE_KAPA_SOURCE_GROUP_IDS` | The hosted docs assistant is unavailable. |
| WebContainer runtime | `VITE_WEBCONTAINER_API_KEY` where required by the runtime | Other Builder runtimes remain available. |

For a database you own, set `DATABASE_URL` and run `pnpm db:migrate`. OAuth apps must permit the local callback URL, `http://localhost:3000/api/auth/callback/github` or `/google`. Use a persistent session secret when testing saved sessions or encrypted site API keys.

Cloudflare's included model makes real remote requests and can incur usage charges once a Cloudflare API token is supplied. Local storage stays in `.wrangler/state`. Production bindings and deployment configuration remain in `wrangler.jsonc`.

### Local Setup

The documentation for all TanStack projects (except `React Charts`) is hosted on [tanstack.com](https://tanstack.com). In production, doc pages are fetched from GitHub. In development, they're read from your local file system.
The documentation for all TanStack projects (except `React Charts`) is hosted on [tanstack.com](https://tanstack.com). Doc pages are fetched from GitHub. In development, a local copy takes precedence when available. You only need the additional repositories if you're editing their docs.

Create a `tanstack` parent directory and clone this repo alongside the projects:

Expand Down Expand Up @@ -84,3 +110,11 @@ To edit docs for a project, make changes in its `docs/` folder (e.g., `../form/d
… and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>

<!-- Use the force, Luke -->

### TanChat alpha access

TanChat is invite-only, independent of Builder access. Signing in to TanStack does not unlock it. Admins and TanStack maintainers with a linked GitHub account have automatic access and unlimited invites. Maintainer identity comes from the verified GitHub account ID and the site's maintainer catalog, not an editable profile name.

Other users unlock TanChat by redeeming a single-use invite and receive three invites to share. Issuing a link consumes one invite, even if the link expires unused. Links expire after seven days. Account settings links to `/chat-access`, where users can create and copy invites. The main site menu links to TanChat, and accounts without access see the invite page.

Migration `0039_tanchat_invites` adds grants and hashed invite tokens. Server functions and chat HTTP endpoints enforce access independently of the UI. Quota checks lock the issuer account, and redemption locks the invite while granting access and consuming it in one transaction. Invite grants are stored in whichever database you configure. Local development without a database has no invite or account state.
7 changes: 6 additions & 1 deletion content-collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ const posts = defineCollection({
rss: z.boolean().optional(),
excerpt: z.string(),
authors: z.string().array(),
contributors: z.string().array().optional(),
library: libraryListSchema.optional(),
headerImage: z.string().optional(),
headerVideo: z.string().optional(),
headerVideoCaptions: z.string().optional(),
content: z.string(),
redirect_from: z.string().array().optional(),
})
Expand All @@ -45,7 +49,8 @@ const posts = defineCollection({
transform: ({ content, ...post }) => {
// Extract header image (first image after frontmatter)
const headerImageMatch = content.match(/!\[([^\]]*)\]\(([^)]+)\)/)
const headerImage = headerImageMatch ? headerImageMatch[2] : undefined
const headerImage =
post.headerImage ?? (headerImageMatch ? headerImageMatch[2] : undefined)
const redirectFrom = normalizeRedirectFrom(post.redirect_from)

return {
Expand Down
21 changes: 21 additions & 0 deletions desktop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# TanStack desktop

This is the Electron host ported from Gum. It opens `https://tanstack.com/chat` in packaged builds and retains the native browser, folder grants, connected-device transport, and update controller.

Install dependencies from the repository root with `pnpm install`.

For development, start the website, then run:

```sh
TANSTACK_APP_URL=http://127.0.0.1:3000 pnpm dev:desktop
```

Use the origin and port of your running website. The development command installs the declared Electron binary using Electron’s own `install-electron` command. Packaged builds ignore development URL overrides.

`pnpm test:desktop` builds the native folder helper and runs the desktop tests. These also run in the repository’s normal test command.

`pnpm pack:desktop` creates a local app directory in `dist/desktop`. Electron Builder may use an available signing identity. This command does not publish an update.

For a distributable macOS build, configure `TANSTACK_UPDATE_URL` with the HTTPS update directory and provide Apple notarization credentials through `APPLE_KEYCHAIN_PROFILE`, an Apple API key, or the existing Apple ID credential variables. Run `pnpm dist:desktop`. Upload the generated artifacts and update metadata to that same directory after verifying signing and notarization. The command does not publish automatically.

The original release scripts are retained in scripts/desktop-release.mjs and scripts/desktop-publish.mjs. `pnpm verify:desktop-release` checks signing, notarization, artifacts, and update metadata without publishing. `pnpm finalize:desktop-release` can submit notarization and regenerate hashes and blockmaps. `pnpm publish:desktop-release` verifies first, then publishes to the explicitly configured TANSTACK_RELEASE_BUCKET and TANSTACK_UPDATE_URL. The update URL must expose that bucket at its configured directory. Provisioning and publishing still require release approval.
5 changes: 5 additions & 0 deletions desktop/assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Desktop artwork

The TanStack desktop app uses the existing square TanStack logo at `public/images/logos/logo-color-600.png`. Electron Builder converts that PNG into the platform icon format.

The Kody images in this directory are historical source assets from the Gum desktop port. They are not used by the TanStack package. The original koala artwork came from https://github.com/kentcdodds/kody/blob/main/packages/worker/public/logo.png. The squircle and square files were edited variants.
Binary file added desktop/assets/kody-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added desktop/assets/kody-square.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added desktop/assets/kody-squircle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions desktop/build-device-helper.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { execFileSync } from 'node:child_process'
import { fileURLToPath } from 'node:url'
import { mkdirSync } from 'node:fs'
const directory = fileURLToPath(new URL('./native/', import.meta.url))
mkdirSync(directory, { recursive: true })
execFileSync(
'cc',
[
'-O2',
'-Wall',
'-Wextra',
'-Werror',
directory + 'folder-access.c',
'-o',
directory + 'folder-access',
],
{ stdio: 'inherit' },
)
67 changes: 67 additions & 0 deletions desktop/builder.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { execFileSync } from 'node:child_process'
import { fileURLToPath } from 'node:url'

const updateUrl = process.env.TANSTACK_UPDATE_URL
if (updateUrl) {
const url = new URL(updateUrl)
if (
url.protocol !== 'https:' ||
url.username ||
url.password ||
url.search ||
url.hash
) {
throw new Error(
'TANSTACK_UPDATE_URL must be an HTTPS directory URL without credentials or query parameters.',
)
}
}

export default {
beforePack: ({ packager }) => {
execFileSync(
process.execPath,
[fileURLToPath(new URL('./build-device-helper.mjs', import.meta.url))],
{ stdio: 'inherit' },
)
if (!packager.config.forceCodeSigning) return
if (!updateUrl)
throw new Error(
'Set TANSTACK_UPDATE_URL to the hosted native update directory before making a release.',
)
const env = process.env
const notarization =
env.APPLE_KEYCHAIN_PROFILE ||
(env.APPLE_API_KEY && env.APPLE_API_KEY_ID && env.APPLE_API_ISSUER) ||
(env.APPLE_ID && env.APPLE_APP_SPECIFIC_PASSWORD && env.APPLE_TEAM_ID)
if (!notarization)
throw new Error(
'Configure Apple notarization credentials before making a release.',
)
},
appId: 'com.tanstack.desktop',
productName: 'TanStack',
asar: true,
asarUnpack: ['native/folder-access'],
forceCodeSigning: true,
directories: { output: '../dist/desktop' },
files: [
'*.mjs',
'!*.test.mjs',
'!builder.config.mjs',
'preload.cjs',
'package.json',
'native/folder-access',
],
extraMetadata: { nativeUpdates: Boolean(updateUrl) },
publish: updateUrl ? [{ provider: 'generic', url: updateUrl }] : null,
mac: {
icon: '../public/images/logos/logo-color-600.png',
category: 'public.app-category.productivity',
target: ['dmg', 'zip'],
hardenedRuntime: true,
notarize: true,
},
artifactName: 'TanStack-${version}-${arch}.${ext}',
dmg: { sign: true },
}
Loading
Loading