# \[ANN\] StippleCodeMirror.jl - A highlighting editor for the GenieFramework

**URL:** <https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127>\
**Category:** Package Announcements\
**Tags:** webapps, editors, syntax-highlighting\
**Created:** [July 28, 2025, 11:07am UTC](https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127 "2025-07-28T11:07:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [July 28, 2025, 11:07am UTC](https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127/1 "2025-07-28T11:07:12Z")

</div>

I’m happy to announce the release of [StippleCodeMirror.jl](https://github.com/GenieFramework/StippleCodeMirror.jl), a new package in the GenieFramework ecosystem that brings the powerful [CodeMirror](https://codemirror.net/) code editor to your web apps, with built-in syntax highlighting for **Julia** , **Python** , and **JavaScript** — and support for many more languages with minimal setup.

Julia syntax highlighting is supported both via CodeMirror’s native mode or using OhMyREPL color schemes server-side.

💡 **Use case highlight** : StippleCodeMirror.jl can be especially useful for editing server-side files in environments where direct file access is limited or restricted.

Beyond its functionality, this package also serves as a reference for integrating external JavaScript libraries into the GenieFramework in a clean, reactive, and idiomatic way.

👉 Give it a try and feel free to share feedback or contributions!

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/5/f5c4693b48b625713e94c20ffc066122fa9c910c.png)

---

<div class="post-metadata">

**Author:** ![andreeco](https://avatars.discourse-cdn.com/v4/letter/a/d26b3c/32.png) [@andreeco](https://discourse.julialang.org/u/andreeco)\
**Post date:** [July 28, 2025, 4:17pm UTC](https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127/2 "2025-07-28T16:17:41Z")

</div>

This is a useful feature! It can be used to build page editors like Gutenberg, Elementor, or Shopware’s Shopping Experiences, enabling interactive editing interfaces within a web app.

(It would be great if GenieFramework, or a third party, offered a Docker container preconfigured with user management and a page builder. This would make deployment much easier for those who aren’t deeply familiar with Genie’s source code.)

---

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [July 30, 2025, 9:49am UTC](https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127/3 "2025-07-30T09:49:41Z")

</div>

Interesting thought, could be be more precise in what you think the docker image should do? How would you want to use that image?  
Maybe a better idea would be a template that contains a preconfigured Genie app with user management and an admin page and including a Dockerfile to build your own image?

---

<div class="post-metadata">

**Author:** ![andreeco](https://avatars.discourse-cdn.com/v4/letter/a/d26b3c/32.png) [@andreeco](https://discourse.julialang.org/u/andreeco)\
**Post date:** [July 30, 2025, 12:43pm UTC](https://discourse.julialang.org/t/ann-stipplecodemirror-jl-a-highlighting-editor-for-the-genieframework/131127/4 "2025-07-30T12:43:02Z")

</div>

This I already have, but it’s not (yet?) published. It’s built using the source code of GenieAuthentication and GenieAuthorisation, but has been heavily modified. I still need to complete the password reset functionality via email and implement multi-factor authentication and more security things.

```julia-auto
xxx@xxx:~/.julia/dev/AuthPlugin$ tree # Small adjustments
├── files
│ ├── app
│ │ ├── layouts
│ │ │ ├── authapp.jl.html
│ │ │ └── authapp_stipple.jl.html
│ │ └── resources
│ │ ├── accounts
│ │ │ ├── AccountsController.jl
│ │ │ └── views
│ │ │ └── account_index.jl.html
│ │ ├── admins
│ │ │ ├── AdminsController.jl
│ │ │ └── views
│ │ │ └── index.jl.html
│ │ ├── legals
│ │ │ ├── LegalsController.jl
│ │ │ └── views
│ │ │ ├── imprint.jl.html
│ │ │ └── privacy.jl.html
│ │ ├── mains
│ │ │ ├── MainsController.jl
│ │ │ └── views
│ │ │ └── index.jl.html
│ │ └── panels
│ │ ├── PanelsController.jl
│ │ └── views
│ │ └── panels.jl
│ ├── config
│ │ └── initializers
│ │ └── authplugin_init.jl
│ ├── locales
│ │ ├── de
│ │ └── en
│ │ ├── accounts.toml
│ │ ├── admins.toml
│ │ ├── layout.toml
│ │ ├── legals.toml
│ │ └── mains.toml
│ ├── plugins
│ │ └── authplugin.jl
│ └── public
│ └── css
│ ├── authpluginstyle.css
├── index.md
├── LICENSE
├── Manifest.toml
├── Project.toml
├── README.md
├── src
│ ├── Authentication.jl
│ ├── Authorisation.jl
│ ├── AuthPlugin.jl
│ ├── install.jl
│ ├── internal
│ │ ├── AuthautoRoutes.jl
│ │ ├── db
│ │ │ ├── migrations
│ │ │ │ ├── 2019052410085235_create_table_users.jl
│ │ │ │ ├── 2021061519495560_create_table_roles.jl
│ │ │ │ ├── 2021061519503270_create_table_permissions.jl
│ │ │ │ ├── 2021061519532446_create_table_roles_users.jl
│ │ │ │ ├── 2021061519540214_create_table_permissions_roles.jl
│ │ │ │ └── 2024010112000000_create_table_bananas.jl
│ │ │ └── seeds
│ │ │ └── AuthSeeds.jl
│ │ ├── helpers
│ │ │ └── AuthenticationViewHelper.jl
│ │ ├── locales
│ │ │ ├── de
│ │ │ │ ├── authentication.toml
│ │ │ │ ├── mailers.toml
│ │ │ │ └── users.toml
│ │ │ ├── en
│ │ │ │ ├── authentication.toml
│ │ │ │ ├── mailers.toml
│ │ │ │ └── users.toml
│ │ │ ├── es
│ │ │ │ ├── authentication.toml
│ │ │ │ ├── mailers.toml
│ │ │ │ └── users.toml
│ │ │ └── fr
│ │ │ ├── authentication.toml
│ │ │ ├── mailers.toml
│ │ │ └── users.toml
│ │ └── resources
│ │ ├── authentication
│ │ │ ├── AuthenticationController.jl
│ │ │ └── views
│ │ │ ├── forgot.jl.html
│ │ │ ├── login.jl.html
│ │ │ ├── register.jl.html
│ │ │ ├── reset.jl.html
│ │ │ └── success.jl.html
│ │ └── users
│ │ ├── UsersController.jl
│ │ ├── Users.jl
│ │ ├── UsersValidator.jl
│ │ └── views
│ │ ├── admin_access_index.jl.html
│ │ ├── admin_permissions_edit.jl.html
│ │ ├── admin_permissions_index.jl.html
│ │ ├── admin_permissions_new.jl.html
│ │ ├── admin_roles_edit.jl.html
│ │ ├── admin_roles_index.jl.html
│ │ ├── admin_roles_new.jl.html
│ │ ├── admin_users_edit.jl.html
│ │ ├── admin_users_index.jl.html
│ │ ├── admin_users_new.jl.html
│ │ ├── edit.jl.html
│ │ └── index.jl.html
│ ├── Mailers.jl
│ └── SearchLightExt.jl
└── test
    └── runtests.jl

```

This app basically keeps most of the user management in the plugin, so updating is easier. The one how installs it can modify the accounts and admins resources and has some other nice template files to edit.

Installing is simple:

```julia
julia> using Genie, AuthPlugin, SearchLight

julia> # Create a new MVC APP with Genie Generator

julia> AuthPlugin.install(@ __DIR__ ; force=true)

julia> SearchLight.Migrations.init()

julia> AuthPlugin.SearchLightExt.all_up_for!!(AuthPlugin) # run all plugin migrations

julia> AuthPlugin.seed_admin_account!() # create an “admin” user

julia> AuthPlugin.seed_permissions_and_roles!() # populate users/roles/perms

```

The layout can be modified by adjusting a constant dict using plugins/authplugin.jl in his app.

```julia-auto
AuthPlugin.LAYOUT[:user] = "authapp.jl.html" # "authapp_stipple.jl.html"
AuthPlugin.LAYOUT[:admin] = "authapp.jl.html" # "authapp_stipple.jl.html"

```

and so forth…

I also have a nice bash script for deployment which does basically this (the real script is a little different):

- Local: Prepare Secrets

- Local: Build & Package

- Local → Remote: Transfer

- Remote: Deploy  
Over a single `ssh server <<EOF…EOF` block it does:

- Local: Cleanup

* * *

But I do believe that having a ready container where you only need to define a new Stipple app and can adjust other pages via a pagebuilder like in Wordpress is easier for most. And this is where your new package might be handy.

Then one just needs to have a docker file like this (untested) in a folder and the respective Caddyfile:

```julia-auto
services:
  web:
    image: genieframework:latest
    container_name: genieframework
    restart: always
    environment:
      GENIE_ENV: prod
    volumes:
      - genie_db:/app/db/prod.sqlite3
      #- geniedata ?
    secrets:
      - genie_secret
      - openai_api_key

  caddy:
    image: caddy:latest
    container_name: caddy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config

secrets:
  genie_secret:
    file: /home/thisuser/.secrets/GENIE_SECRET.txt
  openai_api_key:
    file: /home/thisuser/.secrets/OPENAI_API_KEY.txt

volumes:
  db:
  #geniedata: ?
  caddy_data:
  caddy_config:

```

```Caddyfile
thiswebsite.de {
    reverse_proxy web:8000
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    }
    tls max.mustermann@musterdomain.de
}

```

and one has just to do:

```bash
cd ~/genieapp
docker compose up -d

```

But this is kind of a whole new product based on the Framework and needs much time to be implemented.

Here are some screenshots. I know that the design could be better… but it’s work in progress.

 ![collage-4images-1](https://global.discourse-cdn.com/julialang/original/3X/4/9/490245c63104ea38d2901a5b6d5bd4decffc9d84.png)  
 ![collage-4images-2](https://global.discourse-cdn.com/julialang/original/3X/5/e/5e384961809f462c2008ae0625f15a5e1300374c.png)  
 ![collage-4images-3](https://global.discourse-cdn.com/julialang/original/3X/f/4/f4687bf6c6bc535131ac26c2f9ff4ce9f74fc197.png)  
 ![collage-4images-4](https://global.discourse-cdn.com/julialang/original/3X/1/a/1a004be01bf70e88c2e5217243d2c482169b9908.png)  
 ![collage-4images-5](https://global.discourse-cdn.com/julialang/original/3X/9/f/9f3eb27059b92f2c71cfaa414e96cae6c23b1deb.png)
