@kupola/kupola
v1.9.16
Published
A lightweight UI toolkit for any web project. No heavy frontend frameworks required.
Maintainers
Readme
Kupola
A lightweight, dependency-free declarative UI component system for server-side rendered web applications.
零外部框架依赖的声明式 UI 组件系统,适用于任何服务端渲染 Web 应用。
HTMX (data fetching) + Alpine.js (declarative interaction) + Bootstrap (component richness) — in one zero-dependency package.
🌐 Languages / 语言
📦 构建工具插件
Vite 插件
// vite.config.js
import { kupola } from '@kupola/kupola/vite';
export default {
plugins: [kupola()]
};配置选项:
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| autoCSS | boolean | true | 自动注入 Kupola CSS |
| autoImport | boolean | true | 自动导入 useDeps/useQuery |
| devTools | boolean | true | 开发模式下启用调试工具 |
| cssPath | string | null | 自定义 CSS 路径 |
| themePreload | boolean | false | 自动注入主题预加载脚本 |
Webpack 插件
// webpack.config.js
const KupolaWebpackPlugin = require('@kupola/kupola/webpack');
module.exports = {
plugins: [new KupolaWebpackPlugin()]
};配置选项:
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| autoCSS | boolean | true | 自动注入 Kupola CSS |
| themePreload | boolean | false | 自动注入主题预加载脚本 |
| cssPath | string | null | 自定义 CSS 路径 |
themePreload 配置说明
默认值:false(v1.9.13 变更)
themePreload 用于在 CSS 加载前设置主题属性,防止主题切换时的闪屏问题。请根据你的使用方式决定是否开启:
| 使用方式 | themePreload | 说明 |
|---------|-------------|------|
| ESM + initTheme() | false(默认) | JS 模块加载时自动初始化,无需预加载 |
| UMD / 纯 CSS | true | 需要在 CSS 加载前设置主题,防止闪屏 |
开启示例:
// Vite
kupola({ themePreload: true })
// Webpack
new KupolaWebpackPlugin({ themePreload: true })📖 Documentation
📦 Build Tool Plugins
Vite Plugin
// vite.config.js
import { kupola } from '@kupola/kupola/vite';
export default {
plugins: [kupola()]
};Options:
| Option | Type | Default | Description |
|--------|------|--------|-------------|
| autoCSS | boolean | true | Auto inject Kupola CSS |
| autoImport | boolean | true | Auto import useDeps/useQuery |
| devTools | boolean | true | Enable dev tools in dev mode |
| cssPath | string | null | Custom CSS path |
| themePreload | boolean | false | Auto inject theme preload script |
Webpack Plugin
// webpack.config.js
const KupolaWebpackPlugin = require('@kupola/kupola/webpack');
module.exports = {
plugins: [new KupolaWebpackPlugin()]
};Options:
| Option | Type | Default | Description |
|--------|------|--------|-------------|
| autoCSS | boolean | true | Auto inject Kupola CSS |
| themePreload | boolean | false | Auto inject theme preload script |
| cssPath | string | null | Custom CSS path |
themePreload Configuration
Default: false (Changed in v1.9.13)
themePreload sets theme attributes before CSS loads to prevent flash of unstyled content during theme switching. Enable it based on your usage pattern:
| Usage Pattern | themePreload | Reason |
|--------------|-------------|--------|
| ESM + initTheme() | false (default) | JS module initializes automatically on load |
| UMD / CSS-only | true | Needs theme set before CSS loads to prevent flash |
Example with themePreload enabled:
// Vite
kupola({ themePreload: true })
// Webpack
new KupolaWebpackPlugin({ themePreload: true })✨ Features
- 50+ UI Components — Buttons, inputs, cards, modals, datepickers, timepickers, heatmap, virtual list, stat cards, and more
- Declarative Data Dependencies —
useDeps()with auto-caching, retry, refresh, and transform - HTTP Client Plugin System — Plug in Axios, @navios/http, or any HTTP client; interceptors preserved
- Reactive Data Binding — Two-way binding with
ref()/store()(Proxy-based) - Dual Themes — Dark-first design with light theme support
- 11 Brand Colors — Switchable brand themes inspired by Chinese traditional colors
- Responsive — PC, Pad, and Phone
- Accessible — WCAG AA compliant
- Form Validation — Built-in validation with custom rules
- Zero Dependencies — Pure HTML/CSS/JavaScript, ~75 KB minified gzipped
- Backend Agnostic — Works with Flask, Django, FastAPI, Gin, Spring Boot, ASP.NET, Express, Rails, Actix-web, and any backend that outputs HTML
- TypeScript Ready — Full type definitions included
🚀 Quick Start
Scaffold (recommended)
Create a fully configured Kupola project in seconds:
npx @kupola/create-kupolaChoose from Static, Flask, FastAPI, or Gin — with dark theme, brand colors, and example pages out of the box.
npm
npm install @kupola/kupola<link rel="stylesheet" href="node_modules/@kupola/kupola/dist/css/kupola.css">
<script src="node_modules/@kupola/kupola/dist/kupola.esm.js" type="module"></script>CDN
<!-- ESM (modern browsers) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/css/kupola.css">
<script src="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/kupola.esm.js" type="module"></script>
<!-- UMD (legacy) -->
<script src="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/kupola.umd.js"></script>📦 Usage
Components (HTML-only, no JS needed)
<button class="ds-btn ds-btn--brand">Primary</button>
<button class="ds-btn ds-btn--outline">Outline</button>
<div class="ds-card">
<div class="ds-card__header">
<h3 class="ds-card__title">Card Title</h3>
</div>
<div class="ds-card__body">Card content</div>
</div>Data Binding
<input type="text" data-bind="user.name:value" placeholder="Name">
<span data-bind="user.name:text"></span>kupolaData.data.user = { name: 'John' };
kupolaData.data.user.name = 'Jane'; // Auto-updates all bound elementsDeclarative Data Dependencies
<div data-deps="users:fetch:/api/users">
<template data-each="users">
<span data-bind="item.name:text"></span>
</template>
</div>import { useDeps } from 'kupola';
useDeps({ users: { url: '/api/users', staleTime: 60000 } });HTTP Client Plugin (Axios Example)
import { configureHttpClient } from 'kupola';
import { createAxiosAdapter } from 'kupola/adapters/axios';
import axios from 'axios';
const api = axios.create({ baseURL: '/api' });
api.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
// All useDeps() requests now go through Axios
configureHttpClient(createAxiosAdapter(api));HTTP Client Plugin (@navios/http Example)
import { configureHttpClient } from 'kupola';
import { createNaviosAdapter } from 'kupola/adapters/navios-http';
import { create } from '@navios/http';
const client = create({ baseURL: '/api' });
client.interceptors.request.use(config => {
config.headers['Authorization'] = `Bearer ${getToken()}`;
return config;
});
configureHttpClient(createNaviosAdapter(client));📖 Documentation
- Usage Guide — Getting started and API reference
- Integration Guide — Framework integration examples
- Kupola vs Vue/React — Architecture comparison
- Contributing — How to contribute
🛠️ Development
npm install # Install dependencies
npm run dev # Dev server (Vite, hot reload)
npm run build # Production build
npm run lint # Lint code
npm run test # Run tests🌐 Browser Support
Chrome, Firefox, Safari, Edge (latest)
✨ 核心特性
- 50+ UI 组件 — 按钮、输入框、卡片、模态框、日期选择器、时间选择器、热力图、虚拟列表、统计卡片等
- 声明式数据依赖 —
useDeps()自动缓存、重试、刷新、数据转换 - HTTP 客户端插件 — 无缝集成 Axios、@navios/http 或任意 HTTP 客户端,保留拦截器
- 响应式数据绑定 — 基于 Proxy 的双向绑定,
ref()/store() - 双主题 — 暗色优先设计,支持亮色主题切换
- 11 种品牌色 — 灵感源自中国传统色的可切换品牌主题
- 响应式 — 适配 PC、平板、手机
- 无障碍 — 符合 WCAG AA 标准
- 表单验证 — 内置验证系统,支持自定义规则
- 零依赖 — 纯 HTML/CSS/JavaScript,minified gzip 约 75 KB
- 后端无关 — 支持 Flask、Django、FastAPI、Gin、Spring Boot、ASP.NET、Express、Rails、Actix-web 等任何输出 HTML 的后端
- TypeScript 支持 — 完整类型定义
🚀 快速开始
脚手架(推荐)
一行命令创建配置好的 Kupola 项目:
npx @kupola/create-kupola支持 Static、Flask、FastAPI、Gin 四种后端模板,自带暗色主题、品牌色和示例页面。
npm 安装
npm install @kupola/kupola<link rel="stylesheet" href="node_modules/@kupola/kupola/dist/css/kupola.css">
<script src="node_modules/@kupola/kupola/dist/kupola.esm.js" type="module"></script>CDN 引入
<!-- ESM(现代浏览器) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/css/kupola.css">
<script src="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/kupola.esm.js" type="module"></script>
<!-- UMD(传统方式) -->
<script src="https://cdn.jsdelivr.net/npm/@kupola/kupola/dist/kupola.umd.js"></script>📦 使用示例
组件(纯 HTML,无需 JS)
<button class="ds-btn ds-btn--brand">主要按钮</button>
<button class="ds-btn ds-btn--outline">描边按钮</button>
<div class="ds-card">
<div class="ds-card__header">
<h3 class="ds-card__title">卡片标题</h3>
</div>
<div class="ds-card__body">卡片内容</div>
</div>数据绑定
<input type="text" data-bind="user.name:value" placeholder="姓名">
<span data-bind="user.name:text"></span>kupolaData.data.user = { name: '张三' };
kupolaData.data.user.name = '李四'; // 所有绑定元素自动更新声明式数据依赖
<div data-deps="users:fetch:/api/users">
<template data-each="users">
<span data-bind="item.name:text"></span>
</template>
</div>import { useDeps } from 'kupola';
useDeps({ users: { url: '/api/users', staleTime: 60000 } });HTTP 客户端插件(Axios 示例)
import { configureHttpClient } from 'kupola';
import { createAxiosAdapter } from 'kupola/adapters/axios';
import axios from 'axios';
const api = axios.create({ baseURL: '/api' });
api.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
// 之后所有 useDeps() 请求自动走 Axios + 拦截器
configureHttpClient(createAxiosAdapter(api));📖 文档
- 使用指南 — 入门与 API 参考
- 集成指南 — 后端框架集成示例
- Kupola 与 Vue/React 对比 — 架构对比
- 贡献指南 — 如何参与贡献
🛠️ 开发
npm install # 安装依赖
npm run dev # 开发服务器(Vite,热更新)
npm run build # 生产构建
npm run lint # 代码检查
npm run test # 运行测试🌐 浏览器支持
Chrome、Firefox、Safari、Edge(最新版本)
🤝 Contributing / 贡献
See CONTRIBUTING.md for details.
🙏 Acknowledgments / 致谢
Kupola is built with the help of these excellent open-source tools:
Build & Dev Tooling:
- Vite — Next generation frontend tooling
- Rollup — ES module bundler
- ESLint — JavaScript linter
- Prettier — Code formatter
- Jest — JavaScript testing framework
HTTP Client Adapters (optional, user-installed):
- Axios — Promise based HTTP client
- @navios/http — Lightweight fetch-based Axios replacement
📄 License
MIT © Kupola Team
