Framework
viewi/viewi avatar
viewi/viewi

Viewi renders PHP components in the browser with no JavaScript framework

Unique and efficient front-end framework for PHP

608 stars28 forksPHPMIT

At a glance

What is it?
Viewi is a PHP front-end framework that compiles component templates into JavaScript and ships a browser port of PHP functions, so a component written in PHP renders on the server and hydrates in the browser without a separate frontend framework. It suits PHP teams who want reactive components, and it is a young project on a 2.x line.
Who is it for?
Adopt Viewi when your team writes PHP and wants reactive components with server rendering and browser hydration without adding a JavaScript framework to the stack. Skip it if your frontend is already built with a modern JavaScript framework, since Viewi's premise is that there is no second framework.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A component is a PHP class and a template that also compiles to JavaScript

The example at the top of the README shows the whole model in two snippets. The template is HTML with component tags and a curly-brace interpolation syntax:

html
<div>
    <Thumbnail blog="$blog" />
    <a href="{$blog->url}">
        <h3>{$blog->title}</h3>
        <p>{$blog->description}</p>
    </a>
    <LikeButton liked="{$blog->favorite}" (click)="like" />
</div>

And the component behind it is a plain PHP class extending BaseComponent, with typed public properties and methods that mutate them:

php
class Blog extends BaseComponent
{
    public BlogModel $blog;

    public function like()
    {
        $this->blog->favorite = !$this->blog->favorite;
    }
}

The two halves meet at the component. The class holds the state and the behaviour, the template renders it, and the (click)="like" attribute wires a browser event to the method. That is the core claim of the framework, a component authored once in PHP and running in both places, rather than a PHP template that emits markup plus a separate JavaScript bundle that reimplements the same logic.

The interesting part is a PHP runtime ported into the browser

The README points at a document called FUNCTIONS.md, described as every PHP function a component can call and how closely its browser version matches PHP. That file is the tell about how the framework works. If a template can call a PHP function, then the browser needs a PHP function, and shipping a PHP interpreter to the browser is not an option, so the functions are ported. The repository structure shows where the work happens, with a src/Viewi/PhpJsFunctions directory that the testing section names directly, and the testing instructions require that after adding or changing a JS port in that directory you add its cases to the parity test data and regenerate FUNCTIONS.md with the functions-doc composer script. The ported set is not the whole of PHP, and the document records how far each browser implementation matches the real one. That is an honest and unusual arrangement, since most projects in this space either limit themselves to a tiny subset of expressions or quietly diverge in behaviour.

The feature set is a mix of rendering modes and reactive behaviour

The repository topics list csr, engine, frontend, html, javascript, php, reactive and ssr, which is a compact statement of the scope. Client-side rendering and server-side rendering are both supported, and the reactive part is what makes the components interactive rather than merely templated. The framework is described as unique and efficient for PHP, and the position it takes is that the frontend and the backend are the same language, so a component does not need a counterpart implementation. The engine lives in src/ alongside the rest of the library, bin/ holds a command line entry point, stubs/ contains type stubs, and tools/ holds developer tooling. The build is a TypeScript project, with a tsconfig.json at the root, so the browser side is compiled from TypeScript sources rather than written by hand, and there is a codeception.yml to run the test suite.

The test suite includes a PHP to JavaScript parity check

The testing section is unusually specific and says more about the project's maturity than the feature list does. Unit tests, including the PHP to JavaScript parity suite, need node on the PATH and run with composer test. All tests run with php vendor/bin/codecept run, unit tests alone with php vendor/bin/codecept run Unit, and a single test with php vendor/bin/codecept run Unit JsTranspilerTest. The JsTranspilerTest is the one that matters for a user of the framework, because it is the test that checks the transpiled browser functions behave like the originals. The maintenance rule is also stated, that after adding or changing a JS port in src/Viewi/PhpJsFunctions you add its cases to tests/Support/Data/parity/ and regenerate FUNCTIONS.md with composer functions-doc, and the scaffolding command for a new test is php vendor/bin/codecept generate:test Unit JsTranspiler. The parity data lives under tests/Support/Data/parity/, so the difference table in the documentation is generated from test cases rather than maintained by hand.

Editor support comes from a VS Code extension

There is an official VS Code extension, Viewi Components, with its source in a separate repository, viewi-vscode. The README describes what it provides: highlighting and autocomplete in templates, and Go to Definition for components, props and global methods. That last item matters more than it sounds. In a framework where a template references a component tag, a prop and a PHP function, the most common friction is not knowing what a component accepts or what a function is called in this context, and a language server that resolves those is the difference between a five minute and a two hour first component. The extension is listed in the Visual Studio marketplace, and the repository also carries a .vscode/ directory and a tsconfig.json, so the project itself is developed with the tooling it publishes.

A production reference exists and it runs without a JavaScript framework

The README has an in production section, and it names a specific application rather than speaking in generalities. Urlicer is described as branded short links, QR codes, team workspaces and click analytics, and it runs its entire frontend on Viewi: server-rendered PHP components hydrated in the browser, with no JavaScript framework, built and maintained by the author of Viewi. That is the most informative line in the readme, because it states the operating conditions rather than the aspirations. A single application written by the library's own author, with a commercial product behind it, is a much better signal than a claim about what the framework enables in general. It also frames the constraint, that the hydration path is the one the author could afford to maintain, which is not necessarily the same path a team with a different server stack would want.

The project is young and moving quickly

The maintenance picture is that of an active 2.x line rather than a settled library. The default branch is v2, and the three most recent releases are v2.9.4, v2.9.3 and v2.9.2, all published on 2026-10-07 within a few hours of each other, which indicates a project shipping as it develops rather than on a release cadence. The last push was on 2026-10-07 as well. The licence is MIT, with the copyright held by Ivan Voitovych from 2020-present and the text in the LICENSE file. The README also states that Viewi is built in the maintainers' free time, and the support section asks for stars, follows on X, pull requests and ideas by mail. The documentation lives at viewi.net/docs, with the introduction page linked, and the Discussions forum on GitHub is the other channel for questions.

Where Viewi is the wrong choice

Three situations argue against it. The first is a project whose frontend is already a modern JavaScript framework, because Viewi's proposition is that you do not need one, and adopting it alongside an existing React or Vue frontend means two component models, two build pipelines and two hydration strategies in one repository. The second is a project that needs a large part of the PHP standard library in the browser, because the ported function set is explicitly a subset and the documentation tracks the gap per function, so a template that leans on a function with a partial browser implementation will behave differently in the browser than on the server, and that is a class of bug that only shows up after hydration. The third is a team that cannot accept a young project. A 2.x line with several releases in a single day, a framework that is the author's own commercial product's frontend, and a public discussion forum rather than a support contract all describe a project with one strong maintainer rather than a governed dependency. The realistic alternative for a PHP team that wants components without a JavaScript framework is a template engine with progressive enhancement, and the difference is that Viewi actually ships reactivity and a browser runtime, which is more capability and more of a dependency at the same time.

Editorial conclusion

Adopt Viewi when your team writes PHP and wants reactive components with server rendering and browser hydration without adding a JavaScript framework to the stack. Skip it if your frontend is already built with a modern JavaScript framework, since Viewi's premise is that there is no second framework. Verify first how closely the browser side of each PHP function you rely on matches the server side, because the FUNCTIONS.md document exists precisely to record those differences, and read the parity test suite before assuming a function behaves identically in both places.

Frequently asked questions

What is Viewi?

Viewi is a front-end framework for PHP, described as unique and efficient. A component is a PHP class extending BaseComponent plus a template, and the same code is rendered on the server and hydrated in the browser, so no separate JavaScript framework is involved.

How does Viewi run PHP functions in the browser?

The browser versions of PHP functions are ported into JavaScript under src/Viewi/PhpJsFunctions, and the FUNCTIONS.md document lists every function a component can call together with how closely its browser version matches PHP. A parity test suite and a data directory under tests/Support/Data/parity/ keep that list honest.

How do I run the Viewi tests?

Unit tests including the PHP to JavaScript parity suite run with composer test and need node on the PATH. All tests run with php vendor/bin/codecept run, unit tests alone with php vendor/bin/codecept run Unit, and a single test with php vendor/bin/codecept run Unit JsTranspilerTest. After changing a JS port, add its cases to the parity data and regenerate FUNCTIONS.md with composer functions-doc.

Is there editor support for Viewi?

Yes, there is a VS Code extension called Viewi Components, with its source in the viewi-vscode repository. It provides highlighting and autocomplete in templates plus Go to Definition for components, props and global methods.

Is Viewi still maintained?

The repository is not archived and the last push was on 2026-10-07, with releases v2.9.4, v2.9.3 and v2.9.2 published the same day. The default branch is v2, the licence is MIT with copyright held by Ivan Voitovych, and the README states that Viewi is built in the maintainers' free time.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. viewi/viewi on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/viewi-viewi.svg)](https://hysenlabs.com/projects/viewi-viewi)

Was this useful?