Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jaxon Core Laravel Package

jaxon-php/jaxon-core

Jaxon core lets PHP classes and functions be called directly from JavaScript in Ajax applications. It exports server-side code to the browser, handles incoming Ajax requests, generates responses, and manages the client-side Jaxon object with configuration and plugins.

Deep Wiki
Context7

Getting Started

Understand what you're installing first. jaxon-php/jaxon-core is the engine, not the Laravel integration. It gives you request parsing, callable-class dispatch, the response/command system, and the plugin API — but no service provider, no config publishing, no route, and no Blade directives. In a Laravel app you almost always want the wrapper:

composer require jaxon-php/jaxon-laravel   # pulls jaxon-core + jaxon-js
php artisan vendor:publish --tag=config    # -> config/jaxon.php

If you're auditing or maintaining a bare-core install, the day-one wiring is: read config (jaxon()->config()->read(...)), register callables, then hand the incoming request to jaxon()->processRequest() from a front controller. That's the whole contract — everything else is optional.

Where to look first

Place Why
config/jaxon.php The single source of truth: export list, request URI, JS lib/app URIs, response format, debug flags
app/Ajax/ (you create it) Convention for exported callable classes; keeps remotely-callable code in one auditable place
vendor/jaxon-php/jaxon-core/src/Plugin/ The extension surface — most "how does this work" questions end here
The network tab Every Jaxon response is a JSON array of commands; reading it explains 90% of bugs
jaxon-php.org Docs are current for v5; blog posts and StackOverflow answers are mostly Xajax/Jaxon 3 era

First use case — replace one jQuery $.ajax round trip.

namespace App\Ajax;

use Jaxon\CallableClass;

class Hello extends CallableClass
{
    public function sayHello(string $name): void
    {
        $this->response->assign('message', 'innerHTML', "Hello {$name}!");
    }
}

Export it (config export.classes, or jaxon()->register(Jaxon::CALLABLE_CLASS, Hello::class) in a service provider's boot()), then in Blade:

@jaxonCss
@jaxonJs

<button onclick="jaxon_app_ajax_hello.sayHello('World').call()">Say hello</button>
<div id="message"></div>

The JS object name is derived: prefix jaxon_ + lowercased fully-qualified class name with \ → _. App\Ajax\Hello → jaxon_app_ajax_hello. Click the button, watch a POST to /jaxon, and you've seen the whole loop.

Implementation Patterns

Prefer response commands over return values for UI work. Returning a value sends it to the JS callback; writing to $this->response mutates the page. In day-to-day Laravel work the response style is usually what you want:

public function save(int $id, string $title): void
{
    $post = Post::findOrFail($id);
    $post->update(['title' => $title]);

    $this->response->assign("title-{$id}", 'innerHTML', e($post->title));
    $this->response->script("window.toast('Saved')");
    $this->response->remove("spinner-{$id}");
}

Send parameters as request objects, not as interpolated strings. Hard-coding onclick="...('World')" breaks the moment the value contains a quote. Use the parameter helpers so Jaxon serializes correctly:

<button onclick="jaxon_app_ajax_hello.sayHello(jaxon.$('name-input')).call()">Go</button>
<form onsubmit="jaxon_app_ajax_hello.save(jaxon.form('post-form')).call(); return false;">

jaxon.$('id') reads an input value; jaxon.form('id') serializes a whole form (including files). Both produce lazy request objects that are only resolved at send time, so they always read current DOM state.

Constructor injection works — lean on it. Under the Laravel wrapper, callable classes are resolved through the container, so __construct(private PostRepository $posts) is fine and is the cleanest way to keep Ajax classes thin.

Chain/join requests when the UI needs sequencing. .call() takes a callback for the return value; use the join/queue helpers when one action must follow another rather than firing three independent requests and racing them.

Authorize every method explicitly. There is no implicit auth boundary: every public method on an exported class is a public HTTP endpoint at your Jaxon URI. Either guard the route in middleware, or put $this->authorize(...)-style checks at the top of each method. Treat exported classes exactly like controllers.

Keep exports static and boring. Config-driven export lists (export.classes) beat scattered register() calls — one grep tells you the entire remote attack surface. Register dynamically only when the set genuinely depends on runtime state.

Testing. Callable classes are plain classes; instantiate them in PHPUnit and assert on the accumulated response commands rather than trying to bootstrap the HTTP layer. Anything that needs the full request cycle belongs in a feature test hitting the Jaxon route.

Gotchas and Tips

Version fragmentation is the biggest trap. v5 config keys, the jaxon() helper, and the JS API differ from v4, which differs heavily from v3 — and most online examples are v3 or Xajax. If a snippet references $jaxon->registerFunction() or xjax_, it will not work. Pin the major version and read the vendor source when in doubt.

CSRF and middleware. The Jaxon endpoint is a POST route inside the web group. If you exclude it from CSRF for convenience, you've opened the whole export surface; keep the token flowing instead. If you see 419s, that's the cause, not Jaxon.

Generated JS lives on disk. The app JS is written to a configured directory and served from a configured URI (js.app.dir / js.app.uri in config). If you add an exported class and the browser still 404s or calls a stale object, that's a missing/undeployed artifact or a permissions problem — not a caching mystery in your app code.

Response format mismatch. core.response.send defaults to JSON. Some plugins (notably jQuery-dependent ones) expect XML; mixing them produces silent no-ops where the request succeeds but nothing happens. Check the response body in the network tab before debugging your PHP.

Debug output is a config flag, not a log channel. Turn on core.debug.on to surface exception messages and trace data in the response. Without it, a thrown exception in a callable typically yields an opaque failure on the client — the single most common source of "my Ajax method does nothing."

Return values and commands coexist. A method that both returns a value and mutates $this->response does both. This is a frequent source of duplicated UI updates; pick one convention per class.

Types arrive loose. Parameters come off the wire and PHP 8 type hints will either coerce or throw depending on strict_types. Cast explicitly ((int) $id) at the boundary rather than trusting the type hint, and validate before touching the database.

Extension points, in order of usefulness: custom response commands (subclass/extend the response to add domain-specific DOM operations so your callables stay declarative), plugins (PluginInterface) for cross-cutting concerns like logging or transaction wrapping, and the dialog/view packages (jaxon-dialogs, view renderers) rather than hand-rolling HTML in assign() calls.

Ecosystem reality check. 74 stars, essentially single-maintainer, with framework bridges maintained separately. It's stable and genuinely good at what it does — progressive-enhancement Ajax without an SPA — but it is a minority stack. Budget for reading the source, keep the exported surface small, and don't expect modern tooling (no TypeScript definitions for the client, no Vite integration). For a greenfield Laravel app, Livewire covers the same ground with far more community support; Jaxon earns its place in legacy migrations, server-rendered apps with heavy existing JS, or codebases already using it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console