
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
Semantq is a fullstack JavaScript framework for writing intuitive reactive web apps as well IoT firmware and applications.
Semantq is a lightweight JavaScript framework designed to simplify modern web development. Its declarative syntax, built-in state management, reactive logic blocks, and seamless full-stack integration make it ideal for both frontend and full-stack projects.
Install Semantq via npm:
npm install semantq
OR install globally to use it anywhere in your system
npm install -g semantq
Run your development server:
npm run dev
Now you can view your app on the browser on the given address.
semantq.config.jssemantq.config.js)Customize project-wide settings:
module.exports = {
targetHost: process.env.TARGET_HOST || 'http://localhost:3000',
pageTitle: 'My Awesome Website',
metaDescription: 'My Awesome Website',
metaKeywords: 'keyword one, keyword two, keyword three',
sitemap: true,
semantqNav: {
enable: true,
containerClass: 'semantq-nav-container',
ulClass: 'semantq-nav-list',
liClass: 'semantq-nav-item',
priorityRoutes: ['/home'],
excludeRoutes: ['/404'],
includeRoutes: {
'/sitemap': '/sitemap',
'/home': '/'
},
hierarchical: true,
parentMenuDisplay: 'inline', // stacked or inline
customLinkTexts: {
badmin: 'User Dashboard',
},
},
};
Other configuration options include:
Create directories under src/routes:
src/routes/about
Then inside the about directory create the file: @page.smq.
You can then compose your component following this component mark up structure:
@script
// your js here
@end
@style
/* css here */
@end
@html
all blocks are optional
Note the @html tag is optional just for your visual clarity - also note that the tag doesn't have a closing tag (@end). If you include a closing tag @end for the @html block the compiler will throw an error.
The HTML standard also works:
<script>
// your js here
</script>
<style>
/* css here */
</style>
<h1> Hello World </h1>
All blocks are optional so... this alone will work:
<h1> Hello World </h1>
With the route created, you can now add a link to it. For example, in your entry page:
`project_root/index.html` you might link to the `about` page like this:
```html
<a href="/about">About Us</a>
Note: All routes must start with a leading /.
If you have enabled the auto-generated Semantq navigation module in your semantq.config.js (by setting SemantqNav: true), then you don’t need to manually build a navigation menu.
Instead, you can simply import and use the SemantqNav component in your pages. See the example below.
@script
import SemantqNav from '$global/SemantqNav';
const someText = 'We are an amazing company.';
@end
@html
<SemantqNav />
<h1>About Us</h1>
<p> { someText } </p>
This will automatically render a file-based menu at the top of your page.
For details on navigation menu configuration and customisation, see Automated Navigation Menu Generation.
Once you’ve mastered Semantq manual route creation, you can take advantage of the Command Line Interface (CLI). This powerful tool automatically generates directories, installs the base files, and provides skeletal tags to help you get started quickly—saving you valuable time in production.
semantq make:route about -l
The command above will create the route: src/routes/about and include all necessary files e.g. src/routes/about/@page.smq and src/routes/about/@layout.smq
Options:
| Option | Description |
|---|---|
-l / --layout | Create layout page for <head> scripts and links |
-a / --auth | Restrict page to signed-in users |
--crud / -c | Generate CRUD abstractions |
--ac | Combine auth + CRUD |
If your page requires additional JS or CSS assets (from a CDN or local files), you can define them in the @layout.smq file within the same route directory.
For example, adding Bootstrap from a CDN:
@head
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
@end
What is FOUC?
FOUC (Flash of Unstyled Content) happens when the browser renders a page’s HTML before its CSS has fully loaded, causing a brief “unstyled” flash.
To reduce FOUC, it’s best to import your CSS directly in the script block of your @page.smq file:
@script
import '/components.css'; // if your css file is in project_root/public/components.css
@end
By importing CSS in the @script block of your @page.smq, Semantq ensures that styles are loaded and applied as part of the rendering pipeline, reducing the chance of unstyled content appearing during page load.
Your JavaScript assets (CDN or local) can still be defined in the layout file, while CSS critical to rendering should be imported at the page level.
The layout file has more blocks such as @script ... @end, @head ...@end, @body ... @end, @footer ..@end - all blocks are optional and you only use what you need. Please see the link to the comprehensive Layout Composition guide for more on this.
<!-- src/components/global/Animation.smq -->
<div class="animation">
<slot> Fall back content from the imported (child) component </slot> <!-- default slot -->
</div>
@script
import Animation from '$global/Animation';
@end
@html
<Animation />
// this will resolve the mark up from the imported component (without the raw slot element )
Final Resolved default slot mark up
<div class="animation">
Fall back content from the imported (child) component
</div>
Note how content was passed from the child component because the parent component (page) did not provide any content to be inserted into the default slot.
If you want to pass content from the parent component (page) see the example below:
@script
import Animation from '$global/Animation';
@end
@html
<Animation>
<h1> My animated heading </h1>
</Animation>
Final resolved mark up:
<div class="animation">
<h1> My animated heading </h1>
</div>
Note The Javascript and CSS in the respective tags (blocks) in your imported component will also be imorted and merged with the main page js and css.
src/components/global/Animation.smqSemantq supports named slots that allow you to keep your main page cleaner while making child components reusable.
⚠️ Warning: The child component should generally have self-contained markup. Prefer using elements like <div> or <section> in the child component to avoid situations where parent-provided content (e.g., a <div>) ends up wrapped in invalid HTML such as a <p>. Modern browsers may tolerate this, but it can lead to unpredictable rendering.
FootnoteCard.smq)@script
//some js for the component
@end
@style
/* some css for the component */
@end
@html
<div class="footnote-card">
<div class="footnote-header">
<slot name="header" />
</div>
<div class="footnote-body">
<slot name="body" />
</div>
<div class="footnote-footer">
<slot name="footer" />
</div>
</div>
OR if you want to include fall back content in the child component named slots.
<div class="footnote-card">
<div class="footnote-header">
<slot name="header">Default Header</slot>
</div>
<div class="footnote-body">
<slot name="body">Default body content goes here. This is the fallback text if no content is provided.</slot>
</div>
<div class="footnote-footer">
<slot name="footer">Default Footer</slot>
</div>
</div>
header, body, and footer.<div> structure to ensure valid HTML regardless of what the parent passes.DocsPage.smq)<FootnoteCard>
<div slot="header">Note</div>
<div slot="body">
This section explains the key usage of Semantq slots.
</div>
<div slot="footer">
<a href="#more-info">Learn more</a>
</div>
</FootnoteCard>
<div class="footnote-card">
<div class="footnote-header">
<div>Note</div>
</div>
<div class="footnote-body">
<div>This section explains the key usage of Semantq slots.</div>
</div>
<div class="footnote-footer">
<div><a href="#more-info">Learn more</a></div>
</div>
</div>
Benefits:
import _ from 'lodash';
Native reactive state library:
@script
const count = $state(0);
const doubled = $derived(() => count.value * 2);
$effect(() => {
console.log(`Current count: ${count.value}`);
});
@end
$state → reactive variable$derived → computed value$effect → auto-run reactive effect$onMount Lifecycle Hook In Semantq:## `$onMount`
The `$onMount` lifecycle hook lets you run JavaScript after a component is mounted and the DOM is ready.
This is useful for attaching event listeners, running animations, or targeting DOM elements without relying on
`document.addEventListener('DOMContentLoaded', ...)`.
$onMount(() => {
// Your DOM-ready logic here
const el = document.querySelector('#myElement');
el.focus();
});
You can also pass an async arrow function into $onMount.
This is useful when you need to fetch data or run other asynchronous logic once the component is mounted.
$onMount(async () => {
try {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
console.log('Fetched data:', data);
// You can now update the DOM or component state with the data
} catch (err) {
console.error('Failed to fetch:', err);
}
});
$onMount?document.addEventListener('DOMContentLoaded', ...)project_root/index.html on the Single Page Application (SPA) contexts.| Module | Description |
|---|---|
| Formique | No-code, low-code Schema Definition Language form builder with API integration |
| AnyGrid | Searchable, paginated, sortable data visualization with on-screen edit/delete API support |
| @semantq/state | Framework-agnostic state management library |
| @semantqQL | MCSR Node.js server (model, controller, service, route) |
| @semantq/auth | Full-stack auth server with database and email support |
| @semantq/ql | JS fetch abstraction and CRUD functions |
| SemantqCommerce | Plug-and-play e-commerce solution (WIP) |
| SemantqProse | SSR blogging & CMS with email marketing (WIP) |
| @semantq/iot | IoT module for embedded systems (WIP) |
| Command | Description |
|---|---|
semantq create myapp | Scaffold a new project |
semantq make:route dashboard --auth --crud | Create an authenticated CRUD route |
semantq install:tailwind | Setup Tailwind CSS |
semantq update | Update core dev modules (with confirmation prompts). Semantq will auto-backup your core_modules directory |
semantq create my_crud_app -fs | Full-stack scaffold (frontend + SemantqQL + auth) |
semantq make:resource Product | Generate a full MCSR resource (model, controller, service, route) |
npm run dev | Run the compiler and render the entry page (project_root/index.html). The local dev server usually runs at: http://localhost:5173/ |
To test or preview your app in real time:
npm run dev
This will compile your project and display the entry page in your browser, usually at:
http://localhost:5173/
Build for final deployment Run:
npm run build
This compiles your entire project and generates a build inside project_root/build, then bundles the browser-ready distribution into project_root/dist.
Note The contents of the project_root/dist directory are what you should deploy to your production server — for example, in the public_html directory on cPanel.
When running the final build for production with auto navigation menu generation enabled, remember to update the targetHost setting in your config with your production domain (e.g., https://mywebsitename.com). This value is used to generate your navigation menu.
Serve and Preview the production dist on local environment Run:
npx serve dist
This serves the dist directory of your final compiled app. All pages will be available in the browser, usually at: http://localhost:3000
Semantq Interpolation capabilities enable you to bring JavaScript expressions into html.
@script
const name = 'John';
let count = $state(0);
@end
@html
<h1> Hello {name} </h1>
<p> Clicked: {count} {count > 0 ? 'times' : 'time'} </p>
<button @click={increment}>Click Me</button>
Logic blocks let you express conditional rendering and iteration directly inside your templates using a declarative syntax. Instead of writing imperative JavaScript for every case, you can describe the structure of your UI in plain markup (@if, @else, @each). This keeps your code cleaner, closer to the HTML, and easier to reason about — especially when working with dynamic data that should map naturally to the DOM.
@if and @each Logic Blocks<h1>Dashboard</h1>
@if(items.length > 0)
@each(items as item)
@if(item.active)
<li>{item.name}</li>
@else
<li>Member is inactive</li>
@endif
@endeach
@else
<p>No items available</p>
@endif
Suppose we have this items object (array):
const items = [
{ name: "Alice", active: true },
{ name: "Bob", active: false },
{ name: "Charlie", active: true },
{ name: "Musa", active: true }
];
<ul id="list"></ul>
<p id="empty"></p>
<script>
const items = [
{ name: "Alice", active: true },
{ name: "Bob", active: false },
{ name: "Charlie", active: true }
];
const list = document.getElementById('list');
const empty = document.getElementById('empty');
if (items.length > 0) {
list.innerHTML = '';
items.forEach(item => {
const li = document.createElement('li');
li.textContent = item.active ? item.name : 'Member is inactive';
list.appendChild(li);
});
empty.textContent = '';
} else {
empty.textContent = 'No items available';
}
</script>
@if(items.length > 0)
@each(items as item)
@if(item.active)
<li>{item.name}</li>
@else
<li>Member is inactive</li>
@endif
@endeach
@else
<p>No items available</p>
@endif
Both approaches produce the exact same DOM:
<li>Alice</li>
<li>Member is inactive</li>
<li>Charlie</li>
Semantq’s declarative logic blocks let you describe the UI in a way that’s cleaner, shorter, and easier to reason about — without writing low-level DOM boilerplate.
@if / @else / @endif and @each / @endeachSemantq can automatically generate a mobile friendly navigation menu based on your defined routes. This reduces boilerplate and ensures your navigation stays consistent as your app grows. Configuration is done inside your semantq.config.js:
semantqNav: {
enable: true,
containerClass: 'semantq-nav-container',
ulClass: 'semantq-nav-list',
liClass: 'semantq-nav-item',
priorityRoutes: ['/home','/about'],
excludeRoutes: ['/404','/auth','/'],
includeRoutes: {
'/services': '/about/frontend',
'/home': '/',
'/search': 'https://google.com'
},
hierarchical: true,
parentMenuDisplay: 'inline',
customLinkTexts: {
admin: 'User Dashboard'
},
}
enable
Turns auto-navigation on or off. If set to false, no nav menu will be generated.
containerClass
Applies a CSS class to the outer navigation container (<nav> element), making it easy to style globally.
ulClass / liClass
Classes applied to the <ul> and <li> elements, so you can fully customise the look and feel of the menu.
This means you can instruct Semantq to generate a navigation menu that suits your custom styles if you don't want to rely on the default css for the navigation menu.
priorityRoutes
An array of routes that should always appear that order in the navigation, regardless of alphabetical order or hierarchy.
excludeRoutes
Routes that should not be shown in the navigation. Common examples are error pages (/404), auth flows (/auth), or the root / route if you don’t want it to appear.
includeRoutes
Lets you explicitly add or remap routes:
'/services': '/about/frontend' makes the /services menu entry point to /about/frontend.'/search': 'https://google.com'.'/home': '/' means the /home menu entry will actually point to /.hierarchical
If true, routes are displayed in a nested structure (dropdowns or tree menu), reflecting folder hierarchy. If false, all routes are displayed flat.
parentMenuDisplay
Controls how parent routes with children are rendered:
"inline" → all menu items are inlined - except for drop downs if hierarchical is true"stacked" → a vertically stacked navigation menucustomLinkTexts
Overrides default link text for specific routes. For example:
customLinkTexts: { admin: 'User Dashboard' }
will display "User Dashboard" instead of "admin".
Given the configuration above, your navigation will render as:
<nav class="semantq-nav-container">
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/">Home</a></li>
<li class="semantq-nav-item"><a href="/about">About</a></li>
<li class="semantq-nav-item"><a href="/about/frontend">Services</a></li>
<li class="semantq-nav-item"><a href="https://google.com" target="_blank">Search</a></li>
<li class="semantq-nav-item"><a href="/admin">User Dashboard</a></li>
</ul>
</nav>
Notice that:
/home was remapped to /./services was linked to /about/frontend./search became an external link.admin route displays as “User Dashboard.”/404, /auth, and / were excluded.hierarchical: trueHierachical menus follow the src/routes folder structure.
Suppose your project has the following route files:
src/routes/
├── home
├── about
├── services/
│ ├── africa
│ ├── asia
│ └── europe
├── contact
hierarchical: trueThe menu generator recognises the nested structure (services/africa, services/asia, etc.) and outputs nested <ul> lists.
<nav class="semantq-nav-container">
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/home">Home</a></li>
<li class="semantq-nav-item"><a href="/about">About</a></li>
<li class="semantq-nav-item">
<a href="/services">Services</a>
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/services/africa">Africa</a></li>
<li class="semantq-nav-item"><a href="/services/asia">Asia</a></li>
<li class="semantq-nav-item"><a href="/services/europe">Europe</a></li>
</ul>
</li>
<li class="semantq-nav-item"><a href="/contact">Contact</a></li>
</ul>
</nav>
The /services route acts as a parent menu item, while /services/africa, /services/asia, and /services/europe appear as dropdown children at the same level.
Note With Semantq, there are no limits to how deep your routes can go. The framework automatically translates directory nesting into fully functional multi-level dropdown menus. Each dropdown item can seamlessly expand into its own nested menu, giving you an infinitely scalable navigation system that grows with your app — without extra configuration.
Here’s a visual hierarchical example to illustrate how hierarchical: true and infinite nesting works in Semantq:
<nav class="semantq-nav-container">
<ul class="semantq-nav-list">
<li class="semantq-nav-item">
<a href="/home">Home</a>
</li>
<li class="semantq-nav-item">
<a href="/services">Services ▾</a>
<ul class="semantq-nav-list">
<li class="semantq-nav-item">
<a href="/services/africa">Africa ▾</a>
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/services/africa/north">North</a></li>
<li class="semantq-nav-item"><a href="/services/africa/south">South</a></li>
</ul>
</li>
<li class="semantq-nav-item">
<a href="/services/asia">Asia ▾</a>
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/services/asia/east">East</a></li>
<li class="semantq-nav-item"><a href="/services/asia/west">West</a></li>
</ul>
</li>
</ul>
</li>
<li class="semantq-nav-item">
<a href="/about">About</a>
</li>
</ul>
</nav>
How it works in Semantq
src/routes automatically maps to a menu item.<ul> lists inside parent <li> items.semantq-nav-container, semantq-nav-list, semantq-nav-item) controls styling and dropdown behaviour.hierarchical: falseIf you turn hierarchy off, the same routes flatten into a single-level list:
<nav class="semantq-nav-container">
<ul class="semantq-nav-list">
<li class="semantq-nav-item"><a href="/home">Home</a></li>
<li class="semantq-nav-item"><a href="/about">About</a></li>
<li class="semantq-nav-item"><a href="/services">Services</a></li>
<li class="semantq-nav-item"><a href="/services/africa">Africa</a></li>
<li class="semantq-nav-item"><a href="/services/asia">Asia</a></li>
<li class="semantq-nav-item"><a href="/services/europe">Europe</a></li>
<li class="semantq-nav-item"><a href="/contact">Contact</a></li>
</ul>
</nav>
⚡ Bonus: You can control how parent items behave with parentMenuDisplay:
"inline" → renders a horizontal menu layout. Dropdowns are preserved if hierarchical: true.
"stacked" → renders a vertically stacked menu layout. Dropdowns are preserved if hierarchical: true.
Automatic menu generation with custom classes, route priorities, and hierarchies
Example command:
semantq make:resource Product
This will create the Model, Controller, Service, and Route (MCSR) resources, with routes automatically mounted by the server.
You can query the generated endpoint directly:
curl -X GET http://localhost:3003/product/products
You can add your Product schema in project_root/semantqQL/prisma/schema.prisma:
model Product {
id Int @id @default(autoincrement())
name String
description String?
price Float
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Then, on your command line, navigate to the backend server:
cd semantqQL
Run the migration to create the Product table in your database:
npx prisma migrate dev --name added_product_model
For more details on the full-stack setup, visit: Semantq Full Stack Guide
The route is automatically prefixed by the resource name (in lowercase).
const fetchProducts = async () => {
const res = await fetch('http://localhost:3003/product/products', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await res.json();
console.log(data);
};
fetchProducts();
import { smQL } from '@semantq/ql';
// api set up
const api = new smQL('http://localhost:3003');
// fetch data example
const response = await api.get('/product/products');
// Extract valid product objects
const products = Object.values(response).filter(
item => typeof item === 'object' && item !== null && !Array.isArray(item)
);
console.log(products);
// DELETE request
const response = await api.delete(`/product/products/${product.id}`);
| Operation | Raw Fetch | smQL |
|---|---|---|
| Setup | Must specify method, headers, JSON handling manually. | Just call new smQL(baseURL). |
| GET Products | fetch('.../product/products', { method: 'GET', headers: {...} }) | await api.get('/product/products') |
| DELETE Products | fetch('.../product/products', { method: 'DELETE' }) | await api.delete('/product/products') |
| JSON Extraction | Must call .json() manually. | Handled internally by smQL. |
| Logging | Must add manually. | Built-in (can enable/disable). |
| Code Clarity | Verbose, repetitive. | Clean, concise, standardised. |
For a comprehensive guide on smQL features, please visit: https://github.com/Gugulethu-Nyoni/smQL
Semantq is open-source software licensed under the MIT License.
FAQs
Semantq is a fullstack JavaScript framework for writing intuitive reactive web apps as well IoT firmware and applications.
We found that semantq demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.