Token导航 LogoToken导航

Agent Skill · 研究检索

lifecycle%2fmigrate-from-nextjs(lifecycle 2fmigrate from Next.js 搜索)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

lifecycle%2fmigrate-from-nextjs 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,暂无第三方扫描结果,按安装量在研究检索类的 73,675 个 Skill 里排第 62,484。

总安装 333周安装 14GitHub Stars 14,326下载 116核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:lifecycle%2fmigrate-from-nextjs(lifecycle 2fmigrate from Next.js 搜索)
来源仓库:https://github.com/tanstack/router
仓库路径:skills/lifecycle%2Fmigrate-from-nextjs
安装命令:
npx skills add https://github.com/tanstack/router --skill lifecycle/migrate-from-nextjs
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/tanstack/router --skill lifecycle/migrate-from-nextjs

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。适用于 Codex、Claude、Cursor、Gemini CLI,通过 GitHub 安装。适合生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码。使用时需结合项目现有设计系统、路由和构建方式。

避免只生成孤立片段,页面改动后应配合本地预览确认效果。

来源仓库内路径:skills/lifecycle%2Fmigrate-from-nextjs

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/tanstack/router --skill lifecycle/migrate-from…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

lifecycle%2fmigrate-from-nextjs 怎么安装?

在终端执行 npx skills add https://github.com/tanstack/router --skill lifecycle/migrate-from-nextjs。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

lifecycle%2fmigrate-from-nextjs 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

lifecycle%2fmigrate-from-nextjs 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

lifecycle%2fmigrate-from-nextjs 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

lifecycle%2fmigrate-from-nextjs 用的人多吗?

公开数据是累计安装 333 次,近一周安装 14 次,下载 116 次,GitHub 14,326 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

lifecycle%2fmigrate-from-nextjs 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 来源仓库有 14,326 星,维护活跃度相对可查。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 要求有安全扫描结论才肯安装的团队。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
lifecycle%2fmigrate-from-nextjs

lifecycle 2fmigrate from Next.js 搜索 · 本页

33314,326需要联网未明确未收录

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Migrate from Next.js App Router to TanStack Start

This is a step-by-step migration checklist. Complete tasks in order.

CRITICAL: TanStack Start is isomorphic by default. ALL code runs in both environments unless you use createServerFn. This is the opposite of Next.js Server Components, where code is server-only by default.
CRITICAL: TanStack Start uses createServerFn, NOT "use server" directives. Do not carry over any "use server" or "use client" directives.
CRITICAL: Types are FULLY INFERRED in TanStack Router/Start. Never cast, never annotate inferred values.

Pre-Migration

  • Create a migration branch
git checkout -b migrate-to-tanstack-start
  • Install TanStack Start
npm i @tanstack/react-start @tanstack/react-router
npm i -D vite @vitejs/plugin-react
  • Remove Next.js
npm uninstall next @next/font @next/image

Concept Mapping

Next.js App RouterTanStack Start
app/page.tsxsrc/routes/index.tsx
app/layout.tsxsrc/routes/__root.tsx
app/posts/[id]/page.tsxsrc/routes/posts/$postId.tsx
app/api/users/route.tssrc/routes/api/users.ts (server property)
"use server" + Server ActionscreateServerFn()
"use client"Not needed (everything is isomorphic)
Server Components (default)All components are isomorphic; use createServerFn for server-only logic
next/navigation useRouteruseRouter() from @tanstack/react-router
next/link Link<Link> from @tanstack/react-router
next/head or metadata exporthead property on route
middleware.ts (edge)createMiddleware() in src/start.ts
next.config.jsvite.config.ts with tanstackStart()
generateStaticParamsprerender config in vite.config.ts

Step 1: Vite Configuration

Replace next.config.js with:

// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [
    tanstackStart(), // MUST come before react()
    viteReact(),
  ],
})

Update package.json:

{
  "type": "module",
  "scripts": {
    "dev": "vite dev",
    "build": "vite build",
    "start": "node .output/server/index.mjs"
  }
}

Step 2: Router Factory

// src/router.tsx
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

export function getRouter() {
  const router = createRouter({
    routeTree,
    scrollRestoration: true,
  })
  return router
}

Step 3: Convert Layout → Root Route

Next.js:

// app/layout.tsx
export const metadata = { title: 'My App' }
export default function RootLayout({ children }) {
  return (
    <html>
      <body>{children}</body>
    </html>
  )
}

TanStack Start:

// src/routes/__root.tsx
import type { ReactNode } from 'react'
import {
  Outlet,
  createRootRoute,
  HeadContent,
  Scripts,
} from '@tanstack/react-router'

export const Route = createRootRoute({
  head: () => ({
    meta: [
      { charSet: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { title: 'My App' },
    ],
  }),
  component: RootComponent,
})

function RootComponent() {
  return (
    <html>
      <head>
        <HeadContent />
      </head>
      <body>
        <Outlet />
        <Scripts />
      </body>
    </html>
  )
}

Step 4: Convert Pages → File Routes

Next.js:

// app/posts/[id]/page.tsx
export default function PostPage({ params }: { params: { id: string } }) {
  // ...
}

TanStack Start:

// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/posts/$postId')({
  component: PostPage,
})

function PostPage() {
  const { postId } = Route.useParams()
  // ...
}

Key differences:

  • Dynamic segments use $param not [param]
  • Params accessed via Route.useParams() not component props
  • Route path in filename uses . or / separators

Step 5: Convert Server Actions → Server Functions

Next.js:

// app/actions.ts
'use server'
export async function createPost(formData: FormData) {
  const title = formData.get('title') as string
  await db.posts.create({ title })
}

TanStack Start:

// src/utils/posts.functions.ts
import { createServerFn } from '@tanstack/react-start'

export const createPost = createServerFn({ method: 'POST' })
  .inputValidator((data) => {
    if (!(data instanceof FormData)) throw new Error('Expected FormData')
    return { title: data.get('title')?.toString() || '' }
  })
  .handler(async ({ data }) => {
    await db.posts.create({ title: data.title })
    return { success: true }
  })

Step 6: Convert Data Fetching

Next.js Server Component:

// app/posts/page.tsx (Server Component — server-only by default)
export default async function PostsPage() {
  const posts = await db.posts.findMany()
  return <PostList posts={posts} />
}

TanStack Start:

// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'

const getPosts = createServerFn({ method: 'GET' }).handler(async () => {
  return db.posts.findMany()
})

export const Route = createFileRoute('/posts')({
  loader: () => getPosts(), // loader is isomorphic, getPosts runs on server
  component: PostsPage,
})

function PostsPage() {
  const posts = Route.useLoaderData()
  return <PostList posts={posts} />
}

Step 7: Convert API Routes → Server Routes

Next.js:

// app/api/users/route.ts
export async function GET() {
  const users = await db.users.findMany()
  return Response.json(users)
}

TanStack Start:

// src/routes/api/users.ts
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/api/users')({
  server: {
    handlers: {
      GET: async () => {
        const users = await db.users.findMany()
        return Response.json(users)
      },
    },
  },
})

Step 8: Convert Navigation

Next.js:

import Link from 'next/link'
;<Link href={`/posts/${post.id}`}>View Post</Link>

TanStack Start:

import { Link } from '@tanstack/react-router'
;<Link to="/posts/$postId" params={{ postId: post.id }}>
  View Post
</Link>

Never interpolate params into the to string. Use params prop.

Step 9: Convert Middleware

Next.js:

// middleware.ts
export function middleware(request: NextRequest) {
  const token = request.cookies.get('session')
  if (!token) return NextResponse.redirect(new URL('/login', request.url))
}
export const config = { matcher: ['/dashboard/:path*'] }

TanStack Start:

// src/start.ts — must be manually created
import { createStart, createMiddleware } from '@tanstack/react-start'
import { redirect } from '@tanstack/react-router'

const authMiddleware = createMiddleware().server(async ({ next, request }) => {
  const cookie = request.headers.get('cookie')
  if (!cookie?.includes('session=')) {
    throw redirect({ to: '/login' })
  }
  return next()
})

export const startInstance = createStart(() => ({
  requestMiddleware: [authMiddleware],
}))

Step 10: Convert Metadata/SEO

Next.js:

export const metadata = {
  title: 'Post Title',
  description: 'Post description',
}

TanStack Start:

export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params }) => fetchPost(params.postId),
  head: ({ loaderData }) => ({
    meta: [
      { title: loaderData.title },
      { name: 'description', content: loaderData.excerpt },
      { property: 'og:title', content: loaderData.title },
    ],
  }),
})

Post-Migration Checklist

  • Remove all "use server" and "use client" directives
  • Remove next.config.js / next.config.ts
  • Remove app/ directory (replaced by src/routes/)
  • Remove middleware.ts (replaced by src/start.ts)
  • Verify no next/* imports remain
  • Run npm run dev and check all routes
  • Verify server-only code is inside createServerFn (not bare in components/loaders)
  • Check that <Scripts /> is in the root route <body>

Common Mistakes

1. CRITICAL: Keeping Server Component mental model

// WRONG — treating component as server-only (Next.js habit)
function PostsPage() {
  const posts = await db.posts.findMany() // fails on client
  return <div>{posts.map(...)}</div>
}

// CORRECT — use server function + loader
const getPosts = createServerFn({ method: 'GET' }).handler(async () => {
  return db.posts.findMany()
})

export const Route = createFileRoute('/posts')({
  loader: () => getPosts(),
  component: PostsPage,
})

2. CRITICAL: Using "use server" directive

// WRONG — "use server" is Next.js/React pattern
'use server'
export async function myAction() { ... }

// CORRECT — use createServerFn
export const myAction = createServerFn({ method: 'POST' })
  .handler(async () => { ... })

3. HIGH: Interpolating params into Link href

// WRONG — Next.js pattern
<Link to={`/posts/${post.id}`}>View</Link>

// CORRECT — TanStack Router pattern
<Link to="/posts/$postId" params={{ postId: post.id }}>View</Link>

Cross-References

平台分布

Codex

39.48%
按下载量换算46

Claude

27.53%
按下载量换算32

Cursor

19.58%
按下载量换算23

Gemini CLI

10.26%
按下载量换算12

安全审计

暂无安全审计结果可展示。

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills