Swapping a Uni-App Starter's Base Made AI Agents Stop Breaking the Project
theme: qklhk-chocolate
You've probably encountered this: you ask an Agent to add a page to a project, and it modifies the auto-generated pages.json as if it were a source file, or it can't figure out which plugin configuration to touch.
The problem usually isn't the model; it's that the project itself is a black box to the AI.
After swapping the base of wot-starter to oiyo, the main thing I wanted to solve was exactly this: making the project readable for both humans and AI.
If you've used wot-starter, you're probably familiar with it: based on vitese-uni-app, it deeply integrates the Wot UI component library, making it a fairly complete uni-app starter project.
oiyo-starter hasn't completely overturned it. The component library is still Wot UI, and the surrounding pieces like router, charts, and CI are largely retained. What really changed is the engineering base, moving from a patchwork of plugins to the integrated conventions of the oiyo framework.
The table below gives an overview of both sides. I'll pick a few of the most noticeable differences to expand on later.
| Dimension | wot-starter | oiyo-starter |
|---|---|---|
| Engineering Base | vitese-uni-app + a bunch of Vite plugins | Oiyo framework, integrated conventions |
| Config Entry | Scattered across vite.config, manifest.config | Centralized in oiyo.config.ts |
| App Shell | uni-ku-root plugin simulates App.vue | Native OiyoPage / OiyoLayout |
| Pages & Imports | Individual plugin conventions | definePageMeta + Oiyo scan |
| Request Library | Alova | OiyoHttp |
| AI Support | .agent, .cursor/rules | Built-in Skills suite |
| Commands | vite / uni scripts | oiyo dev / build / prepare |
01 Configuration: From Scattered to Centralized
The wot-starter approach is a plugin patchwork. File-based routing, automatic component loading, and auto-importing of APIs each rely on a plugin, with configuration scattered across vite.config, manifest.config, and individual plugin options.
This works, but the cost is that when you want to change a convention, you first need to know which plugin manages it. As a project grows, the mental map of configuration becomes increasingly blurry.
Oiyo's approach consolidates these into a single entry point. Which components, APIs, and directories to scan are all written in oiyo.config.ts:
scan: {
components: ['@wot-ui/components/**/*.vue', /* ... */],
apis: ['apis/*.ts', 'utils/*.ts', 'stores/*.ts', 'pinia', /* ... */],
}
One file lets you see clearly what the project auto-imports and where pages are scanned from. The configuration surface area is smaller, and the memory burden is lighter.
02 App Shell: From Plugin Simulation to Framework Native
uni-app's native App.vue capabilities are limited. To get a true "root component" for mounting global state and layout, wot-starter relies on the uni-ku-root plugin, which is essentially a simulation.
oiyo builds this directly into the framework itself. In App.vue, you directly wrap OiyoPage with OiyoLayout, and define global state using defineRootContext:
// App.vue
<script setup lang="ts">
const { theme, toast, dialog } = defineRootContext<RootContext>(() => {
// ...
})
</script>
<template>
<WdConfigProvider :theme="theme.theme">
<OiyoLayout>
<OiyoPage />
</OiyoLayout>
<WdNotify />
<WdDialog selector="global" />
<WdToast selector="global" />
</WdConfigProvider>
</template>
The page slot is OiyoPage, the layout entry is OiyoLayout, and things shared across pages hang in the root context. The rendering chain is explicit, no longer a plugin simulating things behind the scenes.
03 Pages & Imports: From Plugin Conventions to Framework Conventions
wot-starter's page registration and auto-imports depend on plugin conventions. They work, but each capability corresponds to a plugin, fragmenting the mental model.
oiyo unifies this into two things. Page meta-information is written at the top level of a page using definePageMeta, and routes and pages.json are generated automatically:
definePageMeta({
type: 'home',
layout: 'tabbar',
style: { navigationBarTitleText: 'Home' },
tab: { iconPath: 'static/home.png' }
})
Auto-imports follow the same set of scan conventions. How pages are registered and where symbols come from all converge into the single mental model of oiyo, eliminating the need to switch between documentation for multiple plugins.
04 Request Library: One Less Ecosystem to Integrate, No Missing Capabilities
wot-starter uses Alova, which is good, but requires integrating a separate request ecosystem and configuring an alova.config.ts.
oiyo-starter directly uses the framework's built-in OiyoHttp, same origin, zero extra configuration. A successful request returns only the refined data by default; pass raw: true if you need the status code, clean and straightforward.
In a real project, use createHttp to build a shared instance, deriving layers from "common → auth → business". Write the token once and it takes effect globally. Lifecycle hooks, automatic retries based on idempotency, and request cancellation at any time—these common capabilities are available out of the box.
05 AI Support: Let the Agent Follow Conventions, Less Rework
wot-starter also comes with .agent and .cursor/rules, which is the right direction, but those are scattered prompts. What the Agent reads are fragments.
oiyo-starter has a built-in Skills suite that feeds the entire Oiyo engineering conventions and Wot UI usage patterns to the AI. How to add a page, where the configuration is, how imports work—the Agent understands it at a glance.
Before, asking it to add a sub-package page would often lead it to modify the auto-generated pages.json, or write definePageMeta in the wrong place. Now, the rules are written dead in the Skill, it follows them, and my rework has visibly decreased.
This is also why I built Skills into the template. A project that AI can read is one that newcomers and your future self can quickly pick up.
06 When to Switch This Base
If you are currently using wot-starter and are often troubled by these issues, you can try oiyo-starter: configuration is too scattered, the app shell relies on plugins cobbled together, and AI always modifies code in the wrong places.
Router, uni-echarts, CI, and others are retained, so migration won't feel too unfamiliar. Getting started is also simple; pnpm install will automatically run prepare to generate types and routes, and pnpm dev lets you select a platform to run.
If you are also pondering how to make your project more AI-friendly, welcome to join the group to chat; the group link is at the end of the article. If you find it useful, go to the repository and give it a star. Pulling it down and running it is more direct than reading ten introductions.
About the Author
sky [Skiyee], UI coder, full-stack dev cat, wheel expert.
Github: https://github.com/skiyee
Related Links
- Oiyo Framework: https://oiyo.js.org
- Gitee Repository: https://gitee.com/skiyee/oiyo-starter
- Github Repository: https://github.com/wot-ui/oiyo-starter
- Community: Official Documentation Community
Top 3 of 4 from juejin.cn, machine-translated. The original thread is authoritative.
Where can I see the example project from the video in the article?
The online example project is in progress. For now, you can pull the same project to preview it. Github: https://github.com/wot-ui/oiyo-starter Gitee: https://gitee.com/skiyee/oiyo-starter
Already using it, works great.
Looks very complete, will try it on the next project. [like]