OVS - A pure JavaScript declarative UI, a Vue DSL that lets you write Vue with a more concise, elegant, and flexible syntax, inspired by Kotlin-HTML, SwiftUI, and SolidJS.
English | 中文
Quick Start • Basic Syntax • Advanced Usage • Design Philosophy • Compilation Principles
OVS is a declarative UI syntax extension that lets you write Vue components in a more concise way:
// OVS syntax
div({ class: 'container' }) {
h1 { 'Hello OVS!' }
button({ onClick: handleClick }) { 'Click Me' }
}Features:
- ✅ Pure JavaScript Superset - All JS syntax works
- ✅ Zero Template Directives - No
v-if,v-for, just nativeif/for - ✅ No JSX Required - Native brace syntax, no
className, no{}wrapping - ✅ Full IDE Support - Code completion, type checking, go to definition
- ✅ Vue 3 Runtime - Compiles to efficient Vue render functions
OVS solves the flexibility problem of Vue templates while being more elegant than JSX.
Conditional Rendering:
// ❌ Vue Template - Custom directives, limited flexibility
<template>
<div v-if="isLoggedIn">Welcome, {{ username }}</div>
<div v-else>Please login</div>
</template>
// ❌ JSX - Ternary expressions, hard to read when nested
{isLoggedIn ? <div>Welcome, {username}</div> : <div>Please login</div>}
// ✅ OVS - Native JavaScript, clean and intuitive
if (isLoggedIn) {
div { `Welcome, ${username}` }
} else {
div { 'Please login' }
}List Rendering:
// ❌ Vue Template - v-for directive, special :key syntax
<template>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</template>
// ❌ JSX - .map() callback, requires return and key prop
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
// ✅ OVS - Native for...of, straightforward
ul {
for (const item of items) {
li { item.name }
}
}Complex Logic:
// ❌ Vue Template - Need computed properties or methods for complex logic
// ❌ JSX - Inline logic becomes messy with && and ternary chains
// ✅ OVS - Just write JavaScript!
div {
const total = items.reduce((sum, item) => sum + item.price, 0)
if (total > 100) {
span({ class: 'discount' }) { 'Free shipping!' }
}
for (const item of items) {
if (item.inStock) {
ProductCard({ product: item })
}
}
}| Feature | Vue Template | JSX | OVS |
|---|---|---|---|
| Control Flow | v-if, v-for directives |
&&, ? :, .map() |
Native if, for |
| Class Attribute | class |
className |
class |
| Expression Syntax | {{ }} |
{ } |
Direct reference |
| Learning Curve | Template syntax | JSX rules | Just JavaScript |
| Flexibility | Limited | High | High |
| Readability | Good for simple | Complex nesting | Clean & intuitive |
npm create ovs@latest my-app
cd my-app
npm install
npm run devInstall Ovs Language from VSCode Extensions Marketplace.
Create a .ovs file:
// src/components/Hello.ovs
import { ref } from 'vue'
const count = ref(0)
div({ class: 'hello' }) {
h1 { 'Hello OVS!' }
p { `Count: ${count.value}` }
button({ onClick: () => count.value++ }) { '+1' }
}Use tagName { content } to declare elements:
div { 'Hello World' }
// Nested elements
div {
h1 { 'Title' }
p { 'Content' }
}Use tagName(propsObject) { content } to pass props:
div({ class: 'container', id: 'app' }) {
a({ href: 'https://example.com', target: '_blank' }) {
'Click here'
}
}
// Event handling
button({ onClick: () => console.log('clicked') }) {
'Click Me'
}Write strings or JavaScript expressions directly:
div {
'Static text' // Static text
`Dynamic: ${value}` // Template string
someVariable // Variable
computedValue() // Function call
}Use standard JavaScript conditional statements:
div {
if (isLoggedIn) {
span { `Welcome, ${username}` }
} else {
button { 'Login' }
}
}Use for...of loops:
ul {
for (const item of items) {
li { item.name }
}
}Use the view soft keyword to define reusable components:
// Define component
view Card(state) {
div({ class: 'card' }) {
h2 { state.props.title }
p { state.props.content }
state.children // Render children
}
}
// Use component
Card({ title: 'Hello', content: 'World' }) {
span { 'Extra content' }
}Note:
viewis a soft keyword (contextual keyword), only has special meaning at component declaration position. You can still useviewas a variable name elsewhere:const view = someValue
Code inside #{} won't be rendered to DOM, used for pure logic:
div {
#{
// Pure JS logic here, won't render
const data = processData(rawData)
console.log('Processing...')
}
// This will render
span { data.result }
}Works with Vue's ref and reactive:
import { ref, reactive } from 'vue'
const count = ref(0)
const user = reactive({ name: 'Alice', age: 25 })
div {
p { `Count: ${count.value}` }
p { `Name: ${user.name}` }
button({ onClick: () => count.value++ }) { 'Add' }
}// HelloWorld.ovs
import { ref } from 'vue'
const msg = "You did it!"
const count = ref(0)
div({ class: 'greetings', onClick: () => count.value = 0 }) {
h1({ class: 'green' }) { msg }
#{
// Pure logic code, won't render
console.log('Component rendered')
}
h2 { `Clicked ${count.value} times` }
h3 {
"Built with "
a({ href: 'https://vuejs.org/', target: '_blank' }) { 'Vue 3' }
' + '
a({ href: 'https://github.com/aspect-apps/ovsjs', target: '_blank' }) { 'OVS' }
}
button({ onClick: () => count.value++ }) { 'Click Me' }
}OVS only adds three syntax extensions:
tag {}/tag() {}- Element declarationview Name() {}- Component declaration (viewis a soft keyword, can be used as variable name)#{}- Non-rendering block
Everything else is standard JavaScript, minimal learning curve.
No need to learn JSX syntax, native braces {} are more natural for JavaScript:
// JSX approach
<div className="container">
<h1>{title}</h1>
</div>
// OVS approach
div({ class: 'container' }) {
h1 { title }
}OVS compiler generates precise Source Maps, enabling IDE to:
- Accurately locate original
.ovsfile positions - Provide complete TypeScript type checking
- Support go-to-definition, rename, and other refactoring features
| Component | Description |
|---|---|
| Subhuti | Parser generator framework, define grammar rules with decorators |
| Slime | JavaScript/TypeScript fault-tolerant parser |
| Volar | Language Server framework, provides IDE support |
| Vue 3 | Runtime framework |
test-volar/
├── ovs/ # OVS compiler + runtime
│ ├── ovs-compiler/ # Compiler (Parser + AST transform)
│ └── ovs-runtime/ # Runtime ($OvsHtmlTag + defineOvsComponent)
├── ovs-language/ # VSCode extension
├── create-ovs/ # Project scaffolding
├── vite-plugin-ovs/ # Vite plugin
├── slime/ # JS/TS parser
└── subhuti/ # Parser framework
MIT License
Issues and Pull Requests are welcome!
- Documentation: deepwiki.com/alamhubb/ovsjs
- Topics:
vue-kotlinvue-dsldeclarative-vuedeclarative-ui-syntax-in-vuevue-swiftuivue-fluttervue-solidjsvue-dsl-in-pure-javascriptdeclarative-dsl-vue
OVS - Declarative UI for the Web, Concise & Elegant ✨