Vike: A Modular Alternative to Next.js Built on Vite
Many React developers use Next.js, but it can feel heavy as projects grow. Local dev can slow down, bundle sizes can get big, and strict conventions may become limiting. These all-in-one frameworks are great for fast starts, but their opinions can add overhead when you need more custom behavior.
Vike takes a different path. It is a modular meta-framework built on Vite that focuses on flexibility, developer control, and a stable foundation. This guide breaks down how Vike works, shows key features with practical examples, and gives a fair look at the pros and cons so you can decide if it fits your project.
Core architecture and philosophy
Vike's fundamental characteristic is its identity as a modular meta-framework. Understanding this distinction is essential to grasping its design philosophy.
A meta-framework builds on top of another library (like React or Vue) to provide features like routing, server-side rendering, and build optimizations. Vike's modularity is the key differentiator. Unlike Next.js's monolithic "batteries-included" approach, Vike allows you to include only the features you need. Everything is an optional component you can add to your stack.
This modularity is built upon a stable core with powerful, low-level hooks. The foundation provides confidence for mission-critical applications while retaining flexibility to adapt and evolve your stack over time. Vike is built on Vite, the next-generation frontend tooling providing fast development experience and optimized production builds.
Project history and design goals
Vike launched in 2021 and rebranded in 2023. Since then, it has gained traction in the developer community, now with over 5,000 GitHub stars. Its core philosophy responds directly to perceived complexity and rigidity in larger frameworks. The goal isn't providing every possible feature out of the box, but rather providing a robust, unopinionated foundation that empowers developers to build tailored frameworks or construct applications with precision and control.
Key architectural advantages
UI framework flexibility
Vike's most powerful feature is its UI-agnostic design. The framework allows you to swap UI libraries like React for Vue, or even use both on the same page, without restructuring your entire application.
This flexibility enables several use cases:
Micro-frontends: Vike excels at building micro-frontend architectures where different teams work on different application parts using their preferred technology.
Multi-tenant applications: For apps serving multiple clients with potentially different UI requirements, Vike's ability to swap components or entire pages simplifies customization.
Gradual migrations: When migrating an old application from one framework to another (such as Vue to React), Vike enables incremental rewrites. You can rewrite one page at a time within the same application, a task that's difficult within more rigid frameworks like Next.js.
Performance characteristics
Vike excels in performance primarily due to its minimalist approach. Vike applications ship incredibly small client-side JavaScript bundles. While a standard Next.js application can easily start with a 70-100 KB bundle before you've written much code, Vike apps often start in the 10-15 KB range.
This bundle size reduction has direct impact on key performance metrics:
Faster page loads: Less JavaScript for the browser to download, parse, and execute means users see content faster.
Improved Core Web Vitals: Smaller bundles contribute to better scores for metrics like First Contentful Paint (FCP) and Time to Interactive (TTI).
Better user experience: Especially on mobile devices or slower network connections, this performance difference is substantial.
Deployment with Photon
Vike's deployment story has improved significantly with Photon, a tool that simplifies deploying Vike applications to modern edge platforms like Cloudflare Workers or Vercel Edge Functions.
Edge deployment provides two major advantages:
No cold starts: Your application is always ready to respond, eliminating the initial delay when a serverless function must "wake up."
Low Time To First Byte (TTFB): Because your code runs on servers physically closer to your users globally, the time for the first byte of data to arrive is drastically reduced, making your site feel incredibly responsive.
Stability and ecosystem integration
Vike prides itself on being "boring in a good way." It's MIT-licensed and doesn't undergo radical, breaking changes every six months. This stability provides a predictable and reliable foundation for projects. Furthermore, its unopinionated nature means it integrates well with other popular ecosystem tools. You can easily integrate data validation libraries like Zod, data-fetching libraries like Tanstack Query, or bring your own custom data layer without fighting the framework.
Project structure and configuration
A typical Vike project structure includes:
pages/: Where your routes live. Vike uses file-based routing similar to Next.js. A file like pages/about/+Page.tsx corresponds to the /about route.
components/: Standard location for reusable UI components, whether React, Vue, or another framework.
telefunc/: Special directory for Vike's remote procedure call (RPC) system.
Per-page rendering strategies
One of Vike's most compelling features is the ability to define rendering strategy on a per-page basis through special +config.ts files alongside page components.
For a page that doesn't change often, like a landing page, you can pre-render it at build time. In the pages/index directory, create a +config.ts file:
export default {
// Server-Side Rendering is disabled for this page.
// It will be pre-rendered to HTML at build time.
ssr: false,
};
With this configuration, Vike generates a static index.html file during the build process, ensuring the fastest possible load time for your homepage.
For a page requiring fresh data on every request, like a user dashboard or guestbook, enable server-side rendering:
export default {
// Server-Side Rendering is enabled for this page.
// It will be rendered on the server for every user request.
ssr: true,
};
This tells Vike to render the guestbook page on the server for each user visit, ensuring content is always up-to-date. This granular control—mixing SSG and SSR pages within the same app with a simple boolean—demonstrates Vike's power and simplicity.
Islands architecture implementation
Vike makes it straightforward to implement the "Islands Architecture," where you can have interactive components (islands) from one UI framework embedded within a page rendered by another.
Consider an about page built with React that includes a skills list component written in Vue.
The main React page component:
import React from "react";
import { SkillsIslandWrapper } from "../../components/SkillsIslandWrapper";
export default function AboutPage() {
return (
<div>
<h1>About Me</h1>
<p>This page is rendered with React.</p>
<h2>My Skills</h2>
<SkillsIslandWrapper client:load />
</div>
);
}
The Vue island component:
<template>
<div class="skills-list">
<p>This skills list is rendered using a Vue component!</p>
<ul>
<li v-for="skill in skills" :key="skill">{{ skill }}</li>
</ul>
</div>
</template>
<script setup lang="ts">
const skills = ["React", "Vue", "TypeScript", "Vike"];
</script>
Vike allows you to simply import the Vue component into your React file. By adding the client:load directive, you tell Vike to hydrate this component on the client-side, making it interactive. This seamless interoperability without complex configuration demonstrates Vike's flexible design.
Type-safe RPC with Telefunc
Handling data communication between client and server typically involves setting up API routes, defining REST endpoints, and managing data serialization. Vike simplifies this entire process with Telefunc.
Telefunc allows you to write functions on your server and call them directly from client-side code as if they were local functions, with full end-to-end type safety.
Define the server function in the telefunc/ directory:
// This code only runs on the server!
import { db } from "./database";
export async function addEntry(name: string, message: string) {
if (!name || !message) {
throw new Error("Name and message are required.");
}
const newEntry = await db.guestbook.create({ data: { name, message } });
return newEntry;
}
Call the function from the client in your React (or Vue) component:
import React, { useState } from "react";
import { addEntry } from "../../telefunc/guestbook.telefunc";
export default function GuestbookPage() {
const [name, setName] = useState("");
const [message, setMessage] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
try {
// Just call the server function!
await addEntry(name, message);
alert("Entry added!");
// Here you would re-fetch entries...
} catch (error) {
alert(error.message);
}
};
// ... rest of the form JSX
}
There are no API routes to define and no manual fetch calls. Telefunc handles network communication, serialization, and error handling under the hood, and TypeScript ensures that the types for name and message are correct from your form all the way to your database.
Trade-offs and limitations
Manual configuration requirements
Vike doesn't hold your hand. You're responsible for wiring up more application logic yourself. Unlike Next.js's convenient getServerSideProps function, data fetching in Vike requires using its onBeforeRender hook to fetch data and pass it to your page. While this offers more control, it means writing more boilerplate code for data fetching and caching, which can feel like a step backward for those accustomed to Next.js's conventions.
Ecosystem maturity
As a younger framework, Vike's ecosystem is naturally smaller than Next.js. You won't find a massive plugin market or official, built-in solutions for everything. Features like advanced image optimization or official authentication packages need implementation using community solutions or built from scratch. Additionally, while core documentation is solid, some users find it can be patchy or confusing for more advanced, edge-case scenarios.
Feature parity considerations
Vike is still evolving. It does not currently have full, native support for React Server Components (RSCs), a major feature that Next.js 13+ has heavily invested in. While you can approximate the RSC pattern using Vike's server functions, it's not the same native experience. As with any growing project, you may encounter occasional bugs or quirks more common than in a more mature framework.
Final thoughts
Vike is best when you want more control, strong performance, and long-term flexibility. If Next.js feels too opinionated or heavy as your app grows, Vike is a solid alternative, especially for teams that care about lean bundles and architectural freedom like micro-frontends.
It requires more hands-on setup, but you can start minimal and add only what you need. With Vite’s speed, cross-framework components, and type-safe RPC, it provides a flexible foundation for apps that need to evolve.