Every few months, a new wave of “build anything with code” content appears, and the demos always look impressive. A custom post type in ten lines. A membership site in an afternoon. A job board before lunch.
What those demos skip is the part where someone has to keep it running, if someone is using:
- AI-generated code — it starts as a solution and slowly becomes a burden.
- Established plugins — which address a different problem, JetEngine isn’t just a faster path to functionality: it’s the result of years of real-world use, thousands of installations, security testing, and feedback from developers building job boards, medical directories, membership platforms, and everything in between.
This is particularly important if you’ve observed the agentic development trend and wondered if you can bypass the plugin layer altogether. You can do so, but the key question is whether the outcome remains effective when a client uses it six months later.
What follows is a look at what JetEngine and its companion plugins deliver and what you’re left with when you try to build the same things without them.
According to the Admin Bar’s 2026 WordPress industry survey, nearly 3/4 of respondents (72.8% across 621 businesses) said AI has had a positive impact on their work. That’s not surprising. AI is genuinely useful, and pretending otherwise would be dishonest.
But “positive impact” covers a wide range. Faster copy. Quicker prototypes. Less time spent on boilerplate. What it doesn’t automatically cover is the part that comes after the first draft: the data model that needs to flex, the user roles that multiply, the filtering logic that has to hold up under real traffic, and the client who needs to manage all of it without calling you.
That’s where the conversation gets more interesting.
Who Will Maintain an AI-Generated Website?
Here’s what AI agents are good at creating:
- a working first draft quickly;
- a registration form;
- a custom post type;
- a page template, all done in minutes.
For static sites, prototypes, and content pages, that’s often enough, but it usually falls apart when the project hits a glass ceiling rather than progressing.
Dynamic WordPress plugins solve this differently. Instead of generating code you’ll have to maintain, they give the client an admin interface they can operate themselves (as well as an opportunity to get lifetime updates, in case one enrolls for a Lifetime plan, meaning that the plugins will stay in-tune with the WordPress engine no matter what).
Using the plugins, the dev sets up the architecture once, and further on, the client can extend it without touching the code, just RTFM, and you’re good to go. 🤭
That’s the true deliverable: not a prompt-generated site, but a system someone else can operate and extend.
The Gap Between Vibe-coded and JetEngine-backed Functionality
Let’s start with what AI actually produces when you ask it to build a content structure for a complex site.
The Claude Code can help you create a medical directory with departments, services, and doctors. It will write register_post_type() for each content type, a set of custom fields via add_meta_box(), and a get_posts() call with a meta lookup to retrieve related content. I know a few people who managed to build something with Claude’s help, though they are now quite sure what happens next, because none of them can actually code. 😅
AI code works… In most cases.
Six months later, the client wants to add a new relationship, such as the languages each doctor speaks, or to reassign services to departments. Every change goes back to the developer because the entire data model is in PHP. There’s no interface for the client, and no safe way to modify the structure without breaking the queries that depend on it.
Now, let’s look at a set of features we can try to build with AI (and fail miserably) that anyone with JetEngine in their inventory can build in a fraction of the time and hand off to a client who’ll never need to call them back.
Creating CPTs and CCTs
When building with JetEngine, you’re not just adding Custom Post Types (CPT) to a WordPress site. You’re creating a data management layer, a set of interfaces that sit between the client and their content, allowing them to change, extend, and query that content without developer involvement.
The CPT/CCT is registered in functions.php (AI can write for you a snippet, and what happens next is up to you), a file that basically controls your website.
The configuration starts here: WordPress Dashboard > JetEngine > Post Types.
A CPT created in JetEngine is a structure that a developer can create, and a client can extend by:
The code still runs under the hood; it’s just managed through a GUI instead of an IDE.
This distinction matters most on complex projects like job boards, online classes/school, or membership sites.
Any site where the data model is likely to evolve after launch. Which, in practice, is every website.
But the more important thing is the Relations between your types of content.
Building Relations
JetEngine’s Relations module lets you define named, typed relations between any content objects (posts, users, CCTs) directly in the admin.
The configuration starts here: WordPress Dashboard > JetEngine > Relations.
You set the relation type (“one to many”, “many to many”), name the relation, and from that point on, you can query it, display it in listings, and filter by it anywhere on the site. This is a real Relations List from the MedCenter dynamic template.
Two active relations: departments to services (“One to many”) and services to doctors (“Many to many”). A department offers several services. A service can be performed by multiple doctors.
The equivalent in hand-written or AI-generated code is a custom relations table, a set of meta lookups, and a developer who has to update all three every time the data model changes.
With JetEngine Relations, adding a new relation type is a UI action. Querying it in a listing takes another. That’s not a small difference in workflow. It’s a different category of deliverable.
Adding Meta Boxes and meta fields
Custom fields in WordPress are usually registered globally; they appear on every post, every user profile, regardless of context. That’s fine for simple sites.
The configuration starts here: WordPress Dashboard > JetEngine > Meta Boxes.
Let’s take a LaborTime dynamic template as an example. It has two fundamentally different user roles, which creates a problem where employers and employees need completely different sets of data attached to their profiles.
JetEngine Meta Boxes solve this at the field definition level, not the template level.
This is the configuration for the “Company” meta box in the LaborTime. Three decisions made here that would otherwise require custom code:
- the meta box is assigned to “User” (not posts or taxonomies);
- it’s restricted by role to “Company” and “Administrator” only;
- it’s set to “Edit User & Profile,” meaning company users can edit these fields directly from their own profile page, without WordPress Dashboard access.
Eight fields are defined for the Company meta box: logo, company name, mobile phone, company size, about the company, company URL, public email, and a gallery. Each field has a name/ID, _company-logo, _employer-company-name, _employer-company-size, that becomes a queryable data point anywhere on the site.
This is what a company user profile looks like in the WordPress Dashboard. A company logo media field upload, company name field, phone, size selector, and a rich text editor for “About the company.”
The employee user type has a parallel meta box, different fields, and the same principle. Work experience, portfolio items, skills, and expected salary.
Ask an AI to replicate this. It will write add_meta_box() calls in functions.php, register fields globally, and add current_user_can() checks to hide them in the template. The fields are still there in the database for every user.
The admin UI is the same for everyone. And the dev will have to update the PHP every time the client needs a new field type or a new role.
Using Query Builder
The deeper piece is the Query Builder in JetEngine that already has AI features that can assist you in creating SQL queries.
The configuration starts here: WordPress Dashboard > JetEngine > Query Builder.
This is the Query Builder section in the LaborTime dynamic template.
Twelve named queries, three different data types: “Posts Query,” “Users Query,” and “Custom Content Type Query.” Each one is a reusable configuration: “Count Jobs for Vacancy Type,” “Query for Saved Candidates,” “Query portfolio for Quired User.”
The employer dashboard, the candidate profile page, the saved jobs listing, and the vacancy counter all run on different queries from this list.
Created once in a UI, without writing WP_Query arguments in PHP. They are stored as configurations rather than code. They won’t break during WordPress updates. They can be duplicated and modified without touching functions.php.
If the client wants to add a new listing type, such as internships alongside full-time roles, adding the corresponding query simply involves duplicating an existing one and changing two parameters.
Creating dynamic Listings
Once the website architecture is in place, CPTs, CCTs, Meta Boxes, Relations, and Queries, something still needs to display it.
In a standard WordPress build, that means PHP templates: a loop, some get_post_meta() calls, and HTML wrapped around the output. Changing anything means rewriting code.
The configuration starts here: WordPress Dashboard > JetEngine > Listings/Components.
JetEngine’s Listings/Components feature works much more effectively. A listing template is an Elementor template with Dynamic Field widgets connected to various sources:
- “Posts/Terms/User/Object Data”;
- “Meta Data”;
- “Query Variable”;
- “Options”;
- or a “Relations Hierarchy.”
Inside that template, dynamic widgets pull values from whatever the current source returns:
- title;
- custom field value;
- featured image;
- user meta;
- relation data, and so on.
The template doesn’t know or care what specific content fills it. It knows the field names and renders whatever is there.
Let’s have a look at the Book of the Week listing that’s displayed inside the Paper books mega menu item inside the OnlyBooks dynamic template:
To build something like this with JetEngine, we’ll have to create a chain of connected features, including a Meta Box and JetEngine query for WooCommerce products, and a JetEngine listing.
The MetaBox for WooCommerce products will contain a set of fields, including a _book-of-the-week radio field:
Once we start building a WC Product Query, we’ll use the same radio field value to fetch the product of the week:
Inside the Book of the Week listing template, we’ll use the “Query Builder” as its source, and then we’ll add a bunch of dynamic fields to fetch the product of the week data:
- Dynamic Image widget with Source set to “Featured Image”;
- Dynamic Link widget pulling the book via the Macros “WP Product Title” title;
- Dynamic Link widget pulling the product link.
As you can see, there are no hardcoded values. With AI, every change within such a flow will be a code change. Every code change is a developer task and an opportunity to create more errors.
With JetEngine, most of those changes are Elementor interactions, and the ones that aren’t are Query Builder configurations.
I dare you to recreate this with an AI website builder. 🤭
Using Profile Builder
So far, we’ve covered data structures and querying. Add user accounts to the picture, and the complexity increases fast.
Most sites that involve user accounts need at least two things: different pages for different roles, and content that responds to who’s logged in.
The standard WordPress approach is a single template with conditional logic: is_user_logged_in(), current_user_can(), and a few if-statements. That works for simple cases.
Let’s get back to the LaborTime dynamic template, as it’s a perfect representation of JetEngine’s Profile Builder feature.
The template has two primary user types: employees (looking for work) and companies (posting jobs). These are not variations of the same experience. They’re fundamentally different interfaces that happen to live at the same URL.
An employee’s account shows:
- Personal Info;
- My Profile;
- Saved Jobs;
- Apply for a Job.
A company’s account shows:
- Company Info;
- Post a Job;
- My Profile;
- Saved Candidates.
Neither sees the other’s options. And the public-facing profile for an employee, work experience, portfolio, skills, and salary expectations is a completely different page from a company’s public profile, even though both live under the same /account/ URL pattern.
JetEngine’s Profile Builder handles this at the system level, not the template level.
The configuration starts here: WordPress Dashboard > JetEngine > Profile Builder >AccountPage assigned.
Single user page enabled, with admin bar hidden for non-admins. Admin area access restriction can be toggled on or off, with no code needed. These are system-wide decisions made once, in a convenient UI.
This is the Account Page configuration for the LaborTime dynamic template.
Each subpage has a role assignment for employee, administrator, or company:
- Post a Job page is invisible to employees;
- Saved Jobs is invisible to companies.
Not hidden with CSS, not conditionally rendered with PHP, simply not available to users whose role doesn’t include it.
One account page, two completely different navigation structures, managed from the WordPress Dashboard.
On the Account Page, the Personal Info section is available for all user roles and makes use of the JetEngine Dynamic Visibility feature.
For example, this Employee mobile section with:
- Professional Summary;
- Work experience;
- Portfolio;
- Skills;
- and Salary blocks, is configured with Dynamic Visibility.
Two conditions must both be true for it to appear:
- Condition 1 set to “Is mobile device” and
- Condition 2 set to “User role” and “Employee.”
Ask an AI to replicate this. It will write a current_user_can() check at the top of a template file. One condition. One location. One point of failure is when the role structure changes.
Using Dynamic Visibility
The Profile Builder section touched on Dynamic Visibility in context, when a section is visible only when two conditions are true simultaneously. That’s one example of what the module does.
The full scope is considerably wider, and it’s worth understanding as a standalone capability because it applies to every template on the site, not just membership flows.
Dynamic Visibility is a JetEngine module that adds the same name tab to every Elementor widget, column, section, and container within the Advanced settings tab. Any element on any template can be shown or hidden based on conditions, and those conditions can be combined with “AND/OR” relation.
For example, we have a special content section that we want to display to logged-in subscribers who visit a post with ID 10641.
A block can be made visible with the following set of conditions:
- “User logged in”;
- “User role is” > “Subscriber”;
- “Post ID is” > “10641”;
- Relation type “AND.”
That’s three conditions evaluated together. The alternative in handwritten PHP is a nested conditional that a developer must write, test, maintain, and update each time those parameters change, often wasting a lot of time.
Integrating JetEngine with dynamic forms
If the previous sections explain how data is structured, queried, and displayed, JetFormBuilder shows how data is initially entered into the system. It also highlights the gap between a generated form and a dynamic builder.
Truth be told, we have an AI built into JetFormBuilder that helps describe form contents and generate a draft of the form with a predefined set of fields.
In the LaborTime dynamic template, employers post jobs through a front-end form; no WordPress Dashboard access required.
The form uses the Insert/Update Post action to create a new post within CPT Jobs with a “Published” status.
The entire moderation flow (submission, review, publication) runs through the front end, tied to Profile Builder account subpages, with the Dynamic Visibility feature enabled for the “Post a Job” button, thus controlling who sees what at each step.
Related tutorials:
FAQ
You can write it, but you’ll also be building the admin interface, handling update compatibility, and documenting everything for whoever touches it next. JetEngine has been tested across thousands of real projects and is updated with every major WordPress release. For anything a client will manage after launch, that track record is worth more than a custom solution built in a weekend.
Not necessarily. JetEngine alone covers custom post types, relations, Query Builder, and Profile Builder; that’s most of the data architecture work. JetSmartFilters, JetFormBuilder, and JetWooBuilder come in when the project needs them. Start with what the project actually requires.
Anything where the data model will change, where different users need different experiences, or where the client will manage content on their own after handoff. Which, honestly, describes most serious WordPress projects.
The code lives in theme files and functions.php. No admin UI, no plugin support, and every WordPress update is your problem. Plugin-based builds are maintained by the vendor, remain manageable through a stable admin interface, and don’t require a developer every time something needs to change. On a long-running project, that gap widens every year.
Conclusion
The argument here isn’t against writing code; it’s against writing code for things that are meant to progress and then handing the code to the client.
Using AI assistance for coding makes sense in many situations: building hero blocks, feature grids, and testimonial layouts. It works well for content pages without dynamic data. It’s ideal for creating rapid prototypes that demonstrate layout and flow to clients before the build begins. It also helps generate product descriptions, meta text, and placeholder copy at scale.
Where it runs into trouble is on projects that keep evolving after launch. JetEngine, as well as other Crocoblock plugins, fill this gap because they’re an infrastructure that’s been tested over time and by users across thousands of installs, and they give clients something they can actually use without having to call for help when minor changes are needed.
A WordPress website shouldn’t be a codebase with no comments that someone inherits; it should be a system that anyone with basic knowledge of WordPress can run.
P.S. If you know of a serious, dynamic vibe-coded website, feel free to send us a link.
P.P.S. If you lean toward the AI doomers camp, you might enjoy a WPTuts video, “Will AI Kill Websites in 2027.” 👹