Skip to content
Back to skills

Theokit Frontend

ASecurity

TheoKit frontend — file-based routing, layouts, theoFetch typed client, useAgent, React patterns

  • 5 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 23, 2026
ai-agentstypescriptreactapifrontend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 23, 2026

npx -y skills add usetheokit/theokit --skill theokit-frontend --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Theokit Frontend?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Theokit Frontend
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/usetheokit-theokit-frontend/badge)](https://www.skillsdirectory.com/skills/usetheokit-theokit-frontend)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: theokit-frontend
description: TheoKit frontend — file-based routing, layouts, theoFetch typed client, useAgent, React patterns
user-invocable: false
paths:
  - 'src/app/**'
---

# TheoKit Frontend (React + File-Based Routing)

## File-Based Routing

| File                      | URL          | Purpose                       |
| ------------------------- | ------------ | ----------------------------- |
| `app/page.tsx`            | `/`          | Home page                     |
| `app/layout.tsx`          | (wrapper)    | Root layout (wraps all pages) |
| `app/error.tsx`           | (error)      | Error boundary                |
| `app/loading.tsx`         | (loading)    | Suspense fallback             |
| `app/not-found.tsx`       | (404)        | Not found page                |
| `app/about/page.tsx`      | `/about`     | Nested route                  |
| `app/tasks/[id]/page.tsx` | `/tasks/:id` | Dynamic route                 |

## Typed API Client (theoFetch)

```typescript
import { theoFetch } from 'theokit/client'

// The URL is used literally — build it yourself for a dynamic route.
const tasks = await theoFetch('/api/tasks')
const task = await theoFetch(`/api/tasks/${id}`)

// POST with body. `method` is REQUIRED when the route declares one.
const created = await theoFetch('/api/tasks', {
  method: 'POST',
  body: { title: 'New task' },
})
```

`theoFetch` has **no `params` option.** Its options are `RequestInit` minus `body`/`method`, plus a
conditional `query` and `body` — nothing interpolates a `:id` segment for you. Reach for the
generated client below when you want that; it is the half that knows your route tree.

## App Client (proxy-based)

```typescript
import { createAppClient } from 'theokit/client'

const client = createAppClient()

const tasks = await client.tasks.get()
const task = await client.tasks.id.get({ params: { id: '42' } }) // → GET /api/tasks/42
const created = await client.tasks.post({ body: { title: 'New' } })
```

Three details the generator decides for you, and each is easy to guess wrong:

- **methods are lowercase** — `get`, `post`; the export in your route file stays `GET`
- **a dynamic segment loses its colon** — `app/tasks/[id]` is reached as `client.tasks.id`, not
  `client.tasks[':id']`
- **`params` values are strings** — `{ id: '42' }`; a URL segment has no other type

Segments are otherwise kept **literal**, so a hyphenated route needs bracket access:
`client['agents-config'].get()`. The client mirrors your URLs rather than prettifying them — a
camelCased key once produced a request to a path no route served.

## Agent Streaming

Two client APIs from `theokit/client`:

### useAgent (React hook — most common)

```typescript
import { useAgent } from 'theokit/client'

function ChatUI() {
  const { messages, status, send, reset } = useAgent<{ message: string }>('/api/agents/chat')

  return (
    <div>
      {status === 'streaming' && <p>Thinking...</p>}
      {messages.map(message => (
        <div key={message.id}>
          {message.parts.map((part, i) =>
            part.type === 'text' ? <p key={i}>{part.text}</p> : null
          )}
        </div>
      ))}
      <button onClick={() => send({ message: 'Hello' })}>Send</button>
    </div>
  )
}
```

`messages` is `UIMessage[]` (ai-sdk). Render `message.parts`: text parts
(`part.type === 'text'`, `part.text`) and tool parts (`part.type === 'dynamic-tool'`,
`part.toolName`, `part.state`, `part.output`). Do NOT switch on an `events`/`event.type`
pattern — the wire is `UIMessageStream`, not SSE events.

### consumeUIMessageStream (non-React)

```typescript
import { consumeUIMessageStream } from 'theokit/client'

const response = await fetch('/api/agents/chat', {
  method: 'POST',
  body: JSON.stringify({ message: 'Hello' }),
})
consumeUIMessageStream(response, (message) => {
  console.log(message.parts)
})
```

## Path Aliases

```typescript
import { db } from '@/server/db' // @/ = project root
import { tasks } from '@/server/db/schema'
```

Configured in `tsconfig.json` — works in both server and app code.

## Anti-patterns

- NEVER use raw `fetch('/api/...')` — use `theoFetch` for type safety
- NEVER create pages outside `app/` — they won't be discovered by the router
- NEVER import server code directly in `app/` — use theoFetch or server actions
- NEVER use `useEffect` + `fetch` for data loading — use theoFetch or `useAgent`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.