# Building Cross-Platform Desktop Applications with Electron

> With DS Server, the Text Control editor can be integrated into cross-platform desktop applications built with Electron. Electron is a framework to create native applications with web technologies like JavaScript, HTML, and CSS.

- **Author:** Bjoern Meyer
- **Published:** 2021-03-25
- **Modified:** 2026-07-17
- **Description:** With DS Server, the Text Control editor can be integrated into cross-platform desktop applications built with Electron. Electron is a framework to create native applications with web technologies like JavaScript, HTML, and CSS.
- **5 min read** (856 words)
- **Tags:**
  - DS Server
  - Electron
  - JavaScript
- **Web URL:** https://www.textcontrol.com/blog/2021/03/25/building-cross-platform-desktop-applications-with-electron/
- **LLMs URL:** https://www.textcontrol.com/blog/2021/03/25/building-cross-platform-desktop-applications-with-electron/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2021/03/25/building-cross-platform-desktop-applications-with-electron/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/dsserver.electron

---

[Electron](https://www.electronjs.org/) is a framework that allows you to develop native cross-platform desktop applications based on HTML, JavaScript and CSS. It uses Chromium to render the content and Node.js to access the local file system and the operating system. That allows you to create a Windows or Mac application with local file access.

In combination with DS Server, you can create a desktop application to edit documents using the HTML5-based document editor with local file access.

![TX Text Control in Electron](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/25/a/assets/electron.webp "TX Text Control in Electron")

The following sample shows how to integrate DS Server into an Electron desktop application.

### Prerequisites

1. Create your free DS Server trial token here:  
    [Trial Token](https://www.dsserver.io/trial/)
2. Install [Node.js®](https://nodejs.org/en/download/) and npm, if not done before.

### Creating the Project

1. Create a folder for your project and install Electron there:
    
    ```
    mkdir my-electron-app && cd my-electron-app
    ```
    
    ```
    npm init -y
    ```
    
    ```
    npm i --save-dev electron
    ```
2. Install [Node.js®](https://nodejs.org/en/download/) and npm, if not done before.

### Create the Main Script File

1. Open the project folder in VS Code or your favorite editor:
    
    ```
    code .
    ```
2. In the root of your application, create a file named *main.js* and add the following content:
    
    ```
    const { app, Menu, BrowserWindow, dialog } = require('electron');
    
    var fs = require('fs');
    
    function createWindow () {
      const win = new BrowserWindow({
        width: 800,
        height: 600,
        icon: 'favicon_32x32.png',
        webPreferences: {
          nodeIntegration: true,
        }
      })
    
    const isMac = process.platform === 'darwin'
    
    const template = [
      // { role: 'appMenu' }
      ...(isMac ? [{
        label: app.name,
        submenu: [
          { role: 'about' },
          { type: 'separator' },
          { role: 'services' },
          { type: 'separator' },
          { role: 'hide' },
          { role: 'hideothers' },
          { role: 'unhide' },
          { type: 'separator' },
          { role: 'quit' }
        ]
      }] : []),
      // { role: 'fileMenu' }
      {
        label: 'File',
        submenu: [{
          label: 'Open',
          accelerator: 'CmdOrCtrl+O',
          click() {
            
            dialog.showOpenDialog({
              properties: ['openFile']
            })
            .then(function(fileObj) {
            
              if (!fileObj.canceled) {
    
                fs.readFile(fileObj.filePaths[0], 'base64', function (err, data) {
                  if(err){
                      alert("An error ocurred reading the file :" + err.message);
                      return;
                  }
                 
                  // call external JS to load the document into TXTextControl
                  win.webContents.executeJavaScript(
                    `loadDocument('${data}', '${fileObj.filePaths[0]}')`
                    );
                });
                 
              }
            },
            )
            .catch(function(err) {
               console.error(err)  
            })
         } 
        }
        ]
      },
      // { role: 'viewMenu' }
      {
        label: 'View',
        submenu: [
          { role: 'reload' },
          { role: 'forceReload' },
          { role: 'toggleDevTools' },
          { type: 'separator' },
          { role: 'resetZoom' },
          { role: 'zoomIn' },
          { role: 'zoomOut' },
          { type: 'separator' }
        ]
      },
      // { role: 'windowMenu' }
      {
        label: 'Window',
        submenu: [
          { role: 'minimize' },
          { role: 'zoom' },
          ...(isMac ? [
            { type: 'separator' },
            { role: 'front' },
            { type: 'separator' },
            { role: 'window' }
          ] : [
            { role: 'close' }
          ])
        ]
      }
    ]
    
    const menu = Menu.buildFromTemplate(template)
    
    Menu.setApplicationMenu(menu)
      win.loadFile('index.html')
      win.show()
    }
    
    app.whenReady().then(() => {
      createWindow();
    
      app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
          createWindow();
          
        }
      })
    
    })
    
    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
    ```
    
    The main script defines the entry point of your Electron application that runs the Main process. In this sample, it also contains the application menu definitions. A *File* menu is added to load a local document into TX Text Control.
3. In the root of your application, create a file named *index.html* and add the following content:
    
    ```
    
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Hello Text Control in Electron!</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
        <script src="textcontrol/txtextcontrol-ds-1.0.0.js"></script>
        <script src="textcontrol/fileHandler.js"></script>
        <link href="styles.css" rel="stylesheet">
    </head>
    <body style="background: white;">
      
      <style>
        #txDocumentEditorContainer {
            width: 100%;
            height: 100vH;
            position: relative;
        }
    </style>
    
    <div id="txDocumentEditorContainer"></div>
    
    <script>
        window.addEventListener("load", function () {
            TXTextControl.init({
                containerID: "txDocumentEditorContainer",
                serviceURL: "https://trial.dsserver.io",
                authSettings: {
                    clientId: "",
                    clientSecret: ""
                }
            });
        });
    </script>
    
    </body>
    </html>
    ```
    
    In line 32 and 33, add your private DS Server OAuth credentials.
4. Open the *package.json* file and replace is with the following content:
    
    ```
    {
      "name": "my-electron-app",
      "version": "0.1.0",
      "author": "your name",
      "description": "My Electron app",
      "main": "main.js",
      "scripts": {
          "start": "electron ."
      }
    }
    ```

### Adding Text Control Script Files

1. Create a folder in the root of your project named *textcontrol*.
2. In that new folder, create a file named *fileHandler.js* and add the following content:
    
    ```
    function loadDocument(document, filename) {
    
        var st = TXTextControl.StreamType.InternalUnicodeFormat;
    
        if (filename.endsWith(".docx") === true) {
            st = TXTextControl.StreamType.WordprocessingML; }
        else if (filename.endsWith(".doc") === true) {
            st = TXTextControl.StreamType.MSWord; }
        else if (filename.endsWith(".rtf") === true) {
            st = TXTextControl.StreamType.RichTextFormat; }
        else if (filename.endsWith(".html") === true) {
            st = TXTextControl.StreamType.HTMLFormat; }
        else if (filename.endsWith(".txt") === true) {
            st = TXTextControl.StreamType.PlainText; }
    
        TXTextControl.loadDocument(st, document);
    
    }
    ```
3. In that new folder, create a file named *txtextcontrol-ds-1.0.0.js*. Using a browser, navigate to the following URL and copy the content into the newly created file:
    
    *https://trial.dsserver.io/documenteditor/JS/txtextcontrol-ds-1.0.0.js*

### Starting the Application

1. In the command line console, start the application by typing the following command:
    
    ```
    npm start
    ```

A new native application is started with the TX Text Control (DS Server) document editor. Using the application menu *File -> Load*, you can open local documents (DOC, DOCX, RTF, HTML and TX):

![TX Text Control in Electron](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/25/a/assets/electron-tx.webp "TX Text Control in Electron")

The application is also displayed in the native Windows task bar:

![TX Text Control in Electron](https://s1-www.textcontrol.com/assets/dist/blog/2021/03/25/a/assets/windows-taskbar.webp "TX Text Control in Electron")

### Package the Application

The application can be packaged and deployed using [Electron Forge](https://www.electronforge.io/). It creates an executable application and a setup the fetches used packages during the installation.

1. Use the following commands to install *Electron Forge* in your app folder:
    
    ```
    npm install --save-dev @electron-forge/cli
    ```
    
    ```
    npx electron-forge import
    ```
2. Use the following command to create the distributable:
    
    ```
    npm run make
    ```

You can test this on your own by downloading the sample application from our GitHub account.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [JavaScript: Avoid Flickering and Visual Updates by Grouping Undo Steps](https://www.textcontrol.com/blog/2022/07/25/javascript-avoid-flickering-and-visual-updates-by-grouping-undo-steps/llms.txt)
- [DS Server or TX Text Control? Different Deployment Scenarios](https://www.textcontrol.com/blog/2022/05/03/ds-server-or-tx-text-control-different-deployment-scenarios/llms.txt)
- [Document Editor: JavaScript Object Availability and Order of Events](https://www.textcontrol.com/blog/2022/05/03/documenteditor-javascript-object-availability-and-order-of-events/llms.txt)
- [Using TX Text Control .NET Server in Blazor Server Apps](https://www.textcontrol.com/blog/2022/01/06/using-tx-text-control-net-server-for-aspnet-in-blazor-server-apps/llms.txt)
- [Using DS Server with Blazor](https://www.textcontrol.com/blog/2021/07/15/using-ds-server-with-blazor/llms.txt)
- [Track Changes: Show 'Original' and 'No Markup'](https://www.textcontrol.com/blog/2021/02/18/track-changes-show-original-and-no-markup/llms.txt)
- [JavaScript Helper Classes: Converting Selected Text to Form Fields](https://www.textcontrol.com/blog/2021/02/13/javascript-helper-classes-converting-selected-text-to-form-fields/llms.txt)
- [DS Server: Using DocumentViewer with pure HTML and JavaScript](https://www.textcontrol.com/blog/2021/01/28/ds-server-using-documentviewer-with-pure-html-and-javascript/llms.txt)
- [DS Server Released: On-Premise Document Services](https://www.textcontrol.com/blog/2021/01/21/ds-server-released-on-premise-document-services/llms.txt)
- [Merging Templates using DS Server in ASP.NET Core](https://www.textcontrol.com/blog/2021/01/07/merging-templates-using-ds-server-in-aspnet-core/llms.txt)
- [Using DS Server with pure HTML and JavaScript](https://www.textcontrol.com/blog/2021/01/05/using-ds-server-with-pure-html-and-javascript/llms.txt)
