Welcome to Slingslop
Build web-applications on top of Apache Sling (+ htmx)
No. It's an under-appreciated open-source framework for web-applications in general.
It's currently serving very large sites in form of Adobe Experience Manager (AEM), which is a CMS build on top of Sling.
Sling itself is quite abtract, it doesn't even know what a page is. It's all resources in an unstructured content-tree (JCR), some of them happen to get rendered as HTML. But it does not come with a built-in user interface. You need to code the frontend (HTML, CSS, JavaScript) on your own.
Due to its modularity, Sling consists of more than 300 modules. There is one for almost everything an "enterprise" application server needs. Scheduling, Eventing and Jobs, Cluster Discovery and Distribution, Testing ecosystem, S3/Azure Blobstore, Logging, GraphQL ...
Chances are you don't need any of that; you can start simple.
There is a bit of a learning curve to get started. Even the most simple project needs five modules:
Frontend build with TypeScript and CSS
HTML templates and components
Business-Logic: where things from the real-world get a name (the hard part) and become code
Content: the story to tell with text and images
Server: something that boots, creates a repository, installs all of the above and listens to incoming HTTP requests
This is intimidating at first, but we've get 'separation of concerns' from the start:
Designers, frontend and backend developers, editors and operations can work on the same project, in parallel, without stepping on each others toes. Regardless of the software stack, these concerns have to get adressed in every project — one way or the other.
The page you're readling right now is a Sling app, a static but editable MPA (Multi-Page Application, formerly known as website).
While Sling is perfectly capable of serving headless json-content for an SPA (Single-Page Application, yes there is a module for that too) we will focus on HDA (Hypermedia-Driven Application) driven by htmx.
Keep in mind that Sling can be used in all sorts of integrations. The architecture suggested here exemplifies the simplicity of both, Sling and htmx play together in way that makes one wonder how they do htmx with 'only static endpoints'. It's a great way of explaining the core-concept of Sling by coming from htmx. More on that later.
Slingslop is a project on github that showcases the complete setup. It's not software on it's own, just a plumbing-together of open-source pieces. The license allows you to copy everything for a quick start without the duty to keep your work open-source.
Click here for history on this project
Experiments on this started after the adaptTo conference in 2019, where the Sling Feature Model 1.0 was revealed and two CMSs were presented: Composum Pages and Peregine CMS: "There is no CMS in Sling, now there are suddenly three that are open source". (Third one being Sling CMS presented in 2021).
In short, in combination it's possible to bake two CMSs into the same docker image, which is a silly thing to do but it makes a few important points:
about the application-serverness of Sling: the ability to host multiple complex apps. Side-note: Peregrine renders a vue SPA, completely breaking with AEM's traditional MPA style
about shared infrastucture:
Composum's JCR node-browser (similar to what /crx/de does in AEM)
a user-manager that also allows to set read/write permissions in JCR
a package-manager to up/download content zip-files, which in turn enables deployment of apps in the browser - instead of commandline or sling-feature-model
Technically these three tools are also "only" apps on top of Sling, but shipped with the official Sling Starter. Sling doesn't needs them, they just make live a bit easier.
The maven sling-project-archetype is a good starting point. For the above, only the launcher's feature-model was needed. CMSs were added there, using the Sling Feature Model, which is a higer level building block that offers an additional way of collaboration instead of fine grained modules.
The archetype also comes with an example app for new projects, but it's a plain 'Hello World' experience. How to make it look nice?
This was pre-AI, lacking frontent-skill the idea was to "borrow" around 20 styles from CSS Zen Garden: The Beauty of CSS Design from 2003, take it's oldschool HTML and replace static text by JCR content.
The only "Business-Logic" is to randomly select a design on every load, resulting in confusion. Designs predate smartphones, can't cope with longer texts, some overlay headlines with images. For editing or creating a new page you'd have to use the node-browser.
Apart from the separation of look&feel from content, some lessons can be learned for creating a Sling application from scatch:
Importing existing markup as Sightly script (aka HTL), split it up into includes and components, copy over the CSS, separate markup from text that is stored in JCR data.
In short, htmx (or datastar) enables developers to define dynamic behavior directly in markup. You click a button and some element changes.
In MPAs you click on an anchor-tag and load a new page's HTML. Which is fine, when css+js are properly cached. But the screen flickers a bit.
SPAs load data - usually JSON - and JavaScript modifies the element. Mainsteam web development (and unguided coding-agents) is mostly into SPAs: React, Angular, Vue, Svelte, SolidJS, Qwik, Preact, Lit, ... bringing in complexity. Next you'll need deeplinks (SPA after a few clicks) optimized for search-engines and end up rendering the HTML on the server again (SSR or hydration).
With HPAs the server returns HTML and the element gets replaced. That's it
<div hx-get="/api/greeting"
hx-trigger="click"
hx-swap="innerHTML">
Click me!
</div>It's easy to understand - you look at the response and directly see what is added.
● Any element can issue HTTP requests
● Any event can trigger a request
● Server returns HTML, not JSON
● Swap the response into the DOM
In abstract terms, application-state shifts from the client to the server. This keeps the client simple but also dumb. It doesn't always makes sense to do a sever-call, so in practice you'll end up somewhere in the middle, only with less JavaScript. Just don't do SPA+htmx at the same time, SPA-frameworks often can't cope with changes outside the Shadow DOM.
Sling and htmx are a perfect match, because each element backed by a JCR node like a page or component already comes with endpoints out-of-the-box. So let’s get into Sling basics.
Have a look into JCR with node-browser, to understand how script-resolution works:

Browser requests https://zengarden.motorbrot.org/home.html
On that domain, webserver adds /content/slingslop/zengarden for short URLS (optional, not part of Sling)
Sling maps URLs to JCR tree. The node ‘home’ has the property sling:resourceType ‘slingslop/zengarden/pages/homepage’, which finds the HTML template under /apps/slingslop…
That template then renders subnodes:
<div data-sly-resource="${'./intro/summary' />
with markup fragment found by the same sling:resourceType mechanism under:/apps/slingslop/zengarden/components/intro/summary/summary.html
The component template looks like this and renders “the story”, in this case the property with the name ‘text’:
<div class="summary" id="zen-summary" role="article">
${properties.text @ context='html'}
</div>Now let’s use SlingPostServlet to write.