Build future-proof AI apps

The config-first web stack for
AI and humans

AI generates config that's easy to generate, review, and maintain. A higher-order language between code and natural language.

$npx lowdefy@latest dev
2.6k+stars
4years open source
3K+weekly npm downloads
lowdefy.yaml
lowdefy: '4.5.2'
pages:
 - id: welcome
 type: PageHeaderMenu
 blocks:
 - id: card
 type: Card
 blocks:
 - id: name
 type: TextInput
 properties:
 label: What's your name?
 - id: greeting
 type: Alert
 properties:
 type: success
 message:
 _js: |
                  const n = state('name');
                  return n ? `Hello, ${n}!` : 'Type your name';
 - id: submit
 type: Button
 properties:
 title: Save
 events:
 onClick:
 - id: validate
 type: Validate

Powering enterprise apps in production

AvisLexusBarloworldCourierITFlavaRTT

AI writes code fast but the maintenance doesn't scale

Vibe-coding produces working prototypes. But production needs maintainability, security, and consistency.

AI generates 5000 lines of code that you can't review

Every prompt produces a wall of code. No one has time to audit it all, so bugs and vulnerabilities slip through.

Every AI session creates new standards, destroying quality

There's no consistency between sessions. Each generation is a unique snowflake of dependencies and patterns.

Security vulnerabilities are often an afterthought

SQL injection, XSS, broken auth. LLMs don't audit their output. Neither do most teams.

Dependency updates break everything, across every project

When Next.js ships a breaking change, you have to fix every AI-generated codebase individually.

The Solution

Config-first: the abstraction layer AI needs

A declarative config that sits between JavaScript and natural language. Constrained enough for guarantees, expressive enough for real apps.

50 lines of config vs 500 lines of code

Declarative YAML replaces thousands of lines of boilerplate. Review entire apps at a glance.

Schema-validated. No arbitrary code paths

Every config property is validated against a schema. No room for hidden logic or unexpected behavior.

One framework update upgrades all your apps

Config is stable. Update Lowdefy once, and every app benefits. No migration scripts needed.

Config is interpreted, not executed. Secure by design

No code injection possible. Auth, permissions, and data validation are built into the runtime.

Code generators vs Lowdefy

Lovable, v0, and other code generators produce raw React. Lowdefy produces reviewable, schema-validated config.

Code Generators
~150
import { useState, useEffect } from 'react';
import { useQuery, useMutation } from '@tanstack/react-query';
import { Table, Card, Button, Modal, Form, Input, Select,
  message, Popconfirm, Space, Tag } from 'antd';
import { EditOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';

interface User {
  id: string;
  name: string;
  email: string;
  role: 'admin' | 'user' | 'editor';
  status: 'active' | 'inactive';
  createdAt: Date;
}

const fetchUsers = async (): Promise<User[]> => {
  const res = await fetch('/api/users');
  if (!res.ok) throw new Error('Failed to fetch users');
  return res.json();
};

const updateUser = async (user: Partial<User> & { id: string }) => {
  const res = await fetch(`/api/users/${user.id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(user),
  });
  if (!res.ok) throw new Error('Failed to update user');
  return res.json();
};

const deleteUser = async (id: string) => {
  const res = await fetch(`/api/users/${id}`, { method: 'DELETE' });
  if (!res.ok) throw new Error('Failed to delete user');
};

const createUser = async (user: Omit<User, 'id' | 'createdAt'>) => {
  const res = await fetch('/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(user),
  });
  if (!res.ok) throw new Error('Failed to create user');
  return res.json();
};

export function UserDashboard() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingUser, setEditingUser] = useState<User | null>(null);
  const [form] = Form.useForm();

  const { data: users, isLoading, error, refetch } = useQuery({
    queryKey: ['users'],
    queryFn: fetchUsers,
  });

  const updateMutation = useMutation({
    mutationFn: updateUser,
    onSuccess: () => {
      message.success('User updated successfully');
      refetch();
      handleCloseModal();
    },
    onError: () => message.error('Failed to update user'),
  });

  const deleteMutation = useMutation({
    mutationFn: deleteUser,
    onSuccess: () => {
      message.success('User deleted successfully');
      refetch();
    },
    onError: () => message.error('Failed to delete user'),
  });

  const createMutation = useMutation({
    mutationFn: createUser,
    onSuccess: () => {
      message.success('User created successfully');
      refetch();
      handleCloseModal();
    },
    onError: () => message.error('Failed to create user'),
  });

  const handleEdit = (user: User) => {
    setEditingUser(user);
    form.setFieldsValue(user);
    setIsModalOpen(true);
  };

  const handleCloseModal = () => {
    setIsModalOpen(false);
    setEditingUser(null);
    form.resetFields();
  };

  const handleSubmit = async (values: Partial<User>) => {
    if (editingUser) {
      await updateMutation.mutateAsync({ ...values, id: editingUser.id });
    } else {
      await createMutation.mutateAsync(values as Omit<User, 'id' | 'createdAt'>);
    }
  };

  if (error) return <div>Error loading users</div>;

  const columns = [
    { title: 'Name', dataIndex: 'name', key: 'name', sorter: true },
    { title: 'Email', dataIndex: 'email', key: 'email' },
    {
      title: 'Role',
      dataIndex: 'role',
      key: 'role',
      render: (role: string) => (
        <Tag color={role === 'admin' ? 'red' : role === 'editor' ? 'blue' : 'default'}>
          {role.toUpperCase()}
        </Tag>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => (
        <Tag color={status === 'active' ? 'green' : 'default'}>{status}</Tag>
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: User) => (
        <Space>
          <Button icon={<EditOutlined />} onClick={() => handleEdit(record)} />
          <Popconfirm title="Delete user?" onConfirm={() => deleteMutation.mutate(record.id)}>
            <Button icon={<DeleteOutlined />} danger />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <Card
      title="User Management"
      extra={
        <Button type="primary" icon={<PlusOutlined />} onClick={() => setIsModalOpen(true)}>
          Add User
        </Button>
      }
    >
      <Table columns={columns} dataSource={users} loading={isLoading} rowKey="id" />
      <Modal
        title={editingUser ? 'Edit User' : 'Create User'}
        open={isModalOpen}
        onCancel={handleCloseModal}
        onOk={() => form.submit()}
        confirmLoading={updateMutation.isPending || createMutation.isPending}
      >
        <Form form={form} layout="vertical" onFinish={handleSubmit}>
          <Form.Item name="name" label="Name" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="email" label="Email" rules={[{ required: true, type: 'email' }]}>
            <Input />
          </Form.Item>
          <Form.Item name="role" label="Role" rules={[{ required: true }]}>
            <Select options={[
              { value: 'admin', label: 'Admin' },
              { value: 'editor', label: 'Editor' },
              { value: 'user', label: 'User' },
            ]} />
          </Form.Item>
          <Form.Item name="status" label="Status" rules={[{ required: true }]}>
            <Select options={[
              { value: 'active', label: 'Active' },
              { value: 'inactive', label: 'Inactive' },
            ]} />
          </Form.Item>
        </Form>
      </Modal>
    </Card>
  );
}
  • • Hard to review - need to understand React patterns
  • • Security depends on implementation quality
  • • Every change can introduce bugs
  • • Dependency on specific package versions
Lowdefy Config
~25
id: user_dashboard
type: PageHeaderMenu

requests:
  - id: get_users
    type: MongoDBFind
    connectionId: users

blocks:
  - id: users_card
    type: Card
    properties:
      title: User Management
    blocks:
      - id: users_table
        type: AgGridAlpine
        properties:
          rowData:
            _request: get_users
          columnDefs:
            - field: name
            - field: email
            - field: role
  • • Scan and review in seconds
  • • Schema-validated, secure by default
  • • Framework handles all the complexity
  • • Upgrade framework without changing config

Full-stack, production-ready

Everything you need to build, connect, and deploy data-driven business apps.

Build

Internal Tools & Admin Panels
Customer Portals
Multi-step Forms & Intake
BI Dashboards & Reporting
Approval Workflows
Inventory & Asset Management

Too many apps?

Most teams run 10+ business apps that don't talk to each other. Resonancy builds one purpose-built solution that replaces them all, built on Lowdefy, delivered in weeks.

Sound familiar?

  • Teams losing time to clunky or disconnected systems
  • Key workflow dependencies limit business growth
  • Lost revenue because of mismanaged data
  • Falling behind competitors with more efficient operations

Consolidate Your Stack

Replace 10+ disconnected apps with one purpose-built solution.

Streamline Workflows

Seamlessly integrated systems that free up your team.

Ship in Weeks

Custom apps built fast with Lowdefy, not months.

Connect Everything

Real-time data across your business for reliable insights.

Talk to Resonancy
Services byResonancy
10+
Years building business apps
50+
Internal tools deployed

Built on open source

We build on Lowdefy, our own open source stack. Quick starter modules get you live fast, then we customize for your exact workflows.

What we deliver:

  • One unified app replacing your SaaS dependency
  • A custom solution tailored to your business
  • AI, data science & integrations included
  • Ongoing support & managed hosting

“When people, processes, and technology resonate together, magic happens.”

Gerrie van Wyk
Gerrie van Wyk
Co-founder, Resonancy & Lowdefy

Loved by developers

Teams around the world are building faster with Lowdefy.

Lowdefy has allowed me to quickly test new product ideas without having to write any code. I have even recreated older PHP tools which are now easier to maintain and update.

Jon Bennetts
Jon Bennetts
86-88 Solutions

As a project manager with limited coding knowledge, I've been able to create various financial tracking and academic documentation apps effortlessly. The best part is the supportive community.

Mahdy Arief
Mahdy Arief
Product Manager at Feedloop

Lowdefy is the ideal solution for anyone looking to build a web application. Its simplicity allowed me to create a functional CRUD app in just a few hours.

Ehan Groenewald
Ehan Groenewald
Data Scientist

Ready to build faster?

Get started with Lowdefy in minutes. No signup required, just run one command.

Open source • Apache 2.0