Awesome Open Source
Awesome Open Source

Minimum Viable Editor

A micro content editing system for the express framework and any frontend.

This content editor uses a js object as data format, the same as most express templating engines.

Adds a nice looking medium-editor to every html-tag with a data-mve-html attribute.

To edit a page, add #editor (defined in config) to the url. And then click on the text you want to edit. Press ctrl + s or click the floppydisk in the lower right corner to save.

Editor Attributes


Add a data-mve-text="[path to text in content json]" attribute and the tag becomes contenteditable.


Add a data-mve-number="[path to text in content json]" attribute and the tag becomes contenteditable but only numbers and "." is allowed. The property in json will be a number instead of a string.


Add a data-mve-html="[path to text in content json]" attribute and a medium editor is added to the tag.


Add a data-mve-list="[path to list in content json]" attribute to be able to clone, delete and rearrenge items within the list. The path can be relative to a parent list, add ./ in the begining of the path.

<ul data-mve-list="content.items">
  {{#each content.items}}
    <li data-mve-html="./">{{name}}</li>

The data path for the items become content.items.0, content.items.1.


Changes the scope for the data-mve-* tags below. Makes refactoring and texts in partials easier. And might save some bytes in the html.

<section data-mve-with="article">
  <h2 data-mve-text="./header">{{article.header}}</h2>

data-mve-image (Beta)

Adds an imagefile upload for images.

<img src={{image}} data-mve-image="{{image}} />

Click on the image to upload a new one.


Install package

npm install minimum-viable-editor --save


In your node app:

const mve = require('minimum-viable-editor');

  dataPath : './data';              // folder for content json and uploaded files.
  users : ['user:123']              //users to be able to edit the content in the form username:password

router.get('/content.json', mve.addContent(), (req, res, next) => res.json(req.content));

See setup parameters for more config parameters.

Add a json file in the dataPath folder with your content data. And add the folder assets upload.

Setup parameters

Parameters to pass into mve.setup.

Parameter Default Description
auth mve.basicAuth() Authentification middleware for content routes.
contentPath [dataPath] Folder on server for storage of content.
dataPath ./data Folder on server for content and file storage.
editorUrl /mve Route for mve. Used for communication between server and client
filesPath [dataPath]/files Folder for file uploads.
hash editor Hash to att to url in browser to show the editor. eg. /page#editor
mediumOptions {} Options for the Medium Editor
splitContent false If the content should be splited into multiple files.
storage file Use file storage, more types are in the roadmap as cloud or database storage.
users [] Array of allowed users for content reading and writing. ["user:pwd",...]


Public method in the package.

Method Parameters Description
mve.addContent lang, addMetaData Middleware that adds content to req.content
mve.setup see setup Initializes the editor
mve.getContent lang fetches the content from storage, returns a promise.
mve.getMetaData lang fetches metadata about the javascript assets to load.
mve.basicAuth Middleware for basicAuth, used by the content router. Uses setup.users
mve.treeEditor content returns html for a simple data object editor


And in the html add (in handlebars) :

  <script type="text/javascript" src="{{_mve.loader}}"></script>

Where the handlebars template data is req.content.

Add an extra data-mve attribute to every tag you want to edit. Use the lodash set/get format to define the data property.

(here with handlebars as templating engine)

  <h3 data-mve-text="about.header">{{"about.header}}</h3>
  <img data-mve-image="about.image" src="{{about.image.src}}" />
  <div data-mve-list="{{about.sections}}"
    {{#each about.sections }}
      <div data-mve-html="./text">

Tree editor

MVE also includes a simple json tree editor.

router.get('/content', mve.basicAuth, mve.addContent(), (req, res, next) => {
  res.render('content', {
    html : mve.treeEditor(req.content),
    _mve : req.content._mve


Add a lang parameter to addContent to retrive another language.

router.get('/content', mve.basicAuth, mve.addContent('sv_se'), (req, res, next) => {
  res.render('content', {
    html : mve.treeEditor(req.content),
    _mve : req.content._mve

router.get('/content.json', mve.addContent('sv_se', false), (req, res, next) => {

A sv_se.json need to be added to the data folder. The _mve property in content is updated for the new language.


The editor doesn't provide any kind of security except the basic auth. To change authentification middleware pass a auth middleware to setup as a auth-parameter. Or Implement something more complicated with the advanced setup.

Editing of invisible elements

Since its only possible to edit visible elements you have to create a different page and add these texts as normal elements. To fetch the editor directly instead of adding #editor, use the index.js.

<script type="text/javascript" src="{{_mve.index}}"></script>

Syncronize content

It could be discussed if the data folder with content should be commited and deployed together with the source. It simplifies deployment of new features a lot. To avoid to write over changed content during deployment a sync script is provided. Add to scripts in package.json

"sync-content" : "mve-sync https://[remote server]/content.json ./data/sv_se.json"

And run npm run sync-content before starting on new content and before release. The local content and remote content will be deep merged with the remote content as master.


soon :(

Related Awesome Lists
Top Programming Languages
Top Projects

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Javascript (1,072,185
Editor (31,934
Medium Editor (83