Server Functions Made Simple

Write server-side functions and call them from your client code as if they were local. Built-in validation, TypeScript support, and automatic API documentation.

// greet.server.js
export async function greet(name) {
  return `Hello, ${name}!`;
}

export async function getTime() {
  return new Date().toLocaleTimeString();
}
// App.vue
import { greet, getTime } from './greet.server.js';

export default {
  methods: {
    async sayHello() {
      // Call server functions like regular functions
      const message = await greet('World');
      const time = await getTime();

      this.greeting = `${message} The time is ${time}`;
    }
  }
}
// vite.config.js
import { defineConfig } from 'vite';
import { serverActions } from 'vite-plugin-server-actions';

export default defineConfig({
  plugins: [
    serverActions()
  ]
});

Get Started in Minutes

1 Install the plugin

# Install the plugin
npm install vite-plugin-server-actions

2 Configure Vite

// vite.config.js
import { serverActions } from 'vite-plugin-server-actions';

export default {
  plugins: [
    serverActions()
  ]
}

3 Create server functions

// math.server.js
export async function calculate(a, b) {
  return a + b;
}

4 Use in your app

// App.js
import { calculate } from './math.server.js';

const result = await calculate(10, 5);
console.log(result); // 15

Simple to Start

Just name your files .server.js and export functions. No configuration needed.

Framework Agnostic

Works with React, Vue, Svelte, or vanilla JavaScript. Use your favorite tools.

Auto Import Magic

Import server functions directly in your client code. Vite handles the rest.

Type-Safe

Full TypeScript support with automatic type inference across client and server.

Production Ready

Optimized builds with tree-shaking and automatic Express server generation.

Developer Friendly

Hot reload in development, helpful error messages, and great DX.

Advanced Features

Take it further with validation, TypeScript, and automatic documentation

Built-in Validation with Zod

import { z } from 'zod';

// Define validation schema
const TodoSchema = z.object({
  text: z.string().min(1).max(100),
  priority: z.enum(['low', 'medium', 'high']).optional(),
  fileData: z.string().optional(),
  fileName: z.string().optional()
});

// Server function with automatic validation
export async function addTodo(todo) {
  const newTodo = {
    id: Date.now(),
    ...todo,
    completed: false,
    createdAt: new Date()
  };

  await db.todos.create(newTodo);
  return newTodo;
}

// Attach schema for validation
addTodo.schema = z.tuple([TodoSchema]);
// Import server function like any other module
import { addTodo } from './todo.server.js';

async function handleSubmit() {
  try {
    // Call it like a normal function!
    const todo = await addTodo({
      text: todoText,
      priority: 'high'
    });

    // TypeScript knows the return type
    console.log('Created:', todo);
  } catch (error) {
    // Validation errors are thrown automatically
    console.error('Validation failed:', error);
  }
}
import { defineConfig } from 'vite';
import { serverActions } from 'vite-plugin-server-actions';

export default defineConfig({
  plugins: [
    serverActions({
      // Enable validation with Zod
      validation: {
        enabled: true,
        adapter: 'zod'
      },

      // Generate OpenAPI documentation
      openAPI: {
        enabled: true,
        info: {
          title: 'My App API',
          version: '1.0.0'
        }
      }
    })
  ]
});