diff --git a/packages/language-select/src/index.js b/packages/language-select/src/index.js
index e1285c705851243dcb2dd57f63c9c5cf0fff1004..fffbb546ed404fe797c5b6e06e02993e8226df1d 100644
--- a/packages/language-select/src/index.js
+++ b/packages/language-select/src/index.js
@@ -1,3 +1,3 @@
-import {LanguageSelect} from './vpu-language-select.js';
+import {LanguageSelect} from './language-select.js';
 
 export {LanguageSelect};
\ No newline at end of file
diff --git a/packages/language-select/src/language-select.js b/packages/language-select/src/language-select.js
new file mode 100644
index 0000000000000000000000000000000000000000..27cd64e182e27d9405f41003a059d00314b82c77
--- /dev/null
+++ b/packages/language-select/src/language-select.js
@@ -0,0 +1,133 @@
+import {html, css, LitElement} from 'lit-element';
+import {i18n} from './i18n.js';
+import * as commonStyles from 'vpu-common/styles';
+
+/**
+ * Emits a vpu-language-changed event where event.detail.lang is the new selected language
+ */
+export class LanguageSelect extends LitElement {
+
+    constructor() {
+        super();
+        this._lang = 'de';
+        this.languages = ['de', 'en'];
+
+        this.onExternalChange = this.onExternalChange.bind(this);
+
+        // for the i18next scanner
+        i18n.t('de');
+        i18n.t('de-action');
+        i18n.t('en');
+        i18n.t('en-action');
+    }
+
+    _getNextLanguage(lang) {
+        var index = this.languages.indexOf(lang);
+        var next = this.languages[index + 1];
+        if (typeof next === 'undefined')
+            next = this.languages[0];
+        return next;
+    }
+
+    _getPreviousLanguage(lang) {
+        var index = this.languages.indexOf(lang);
+        var prev = this.languages[index - 1];
+        if (typeof prev === 'undefined')
+            prev = this.languages[this.languages.length - 1];
+        return prev;
+    }
+
+    static get properties() {
+        return {
+            lang: {type: String},
+            next: {type: String},
+            languages: {type: Array},
+        };
+    }
+
+    set lang(value) {
+        const oldValue = this.lang;
+        const oldNext = this.next;
+        this._lang = value;
+        this.requestUpdate('lang', oldValue);
+        this.requestUpdate('next', oldNext);
+
+        if (oldValue !== value) {
+            const event = new CustomEvent("vpu-language-changed", {
+                bubbles: true,
+                composed: true,
+                detail: {'lang': value}
+            });
+            this.dispatchEvent(event);
+
+            // Unlike other cases we use the next language for the translations so that
+            // users not knowing the current language can understand it.
+            // In case of more than two this doesn't make that much sense, but for now..
+            i18n.changeLanguage(this.next);
+        }
+    }
+
+    get lang() {
+        return this._lang;
+    }
+
+    set next(value) {
+        this.lang = this._getPreviousLanguage(value);
+    }
+
+    get next() {
+        return this._getNextLanguage(this.lang);
+    }
+
+    static get styles() {
+        // language=css
+        return css`
+            ${commonStyles.getThemeCSS()}
+
+            :host {
+                display: inline-block;
+            }
+
+            a:hover {
+                background-color: var(--vpu-dark);
+                color: var(--vpu-light);
+                transition: none;
+            }
+
+            a {
+                padding: 0.3em;
+                display: inline-block;
+                text-decoration: none;
+                transition: background-color 0.15s, color 0.15s;
+                color: var(--vpu-dark);
+                border-radius: var(--vpu-border-radius);
+            }
+        `;
+    }
+
+    onExternalChange(e) {
+        this.lang = e.detail.lang
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        window.addEventListener('vpu-language-changed', this.onExternalChange);
+    }
+
+    disconnectedCallback() {
+        document.removeEventListener('vpu-language-changed', this.onExternalChange);
+        super.disconnectedCallback();
+    }
+
+    onClick(e) {
+        e.preventDefault();
+        this.lang = this.next;
+    }
+
+    render() {
+        var linkTitle = i18n.t(this.next + '-action');
+        return html`
+            <a href="#" title="${linkTitle}" @click=${this.onClick}>${this.next.toUpperCase()}</a>
+        `;
+    }
+}
\ No newline at end of file
diff --git a/packages/language-select/src/vpu-language-select-demo.js b/packages/language-select/src/vpu-language-select-demo.js
index 6c3dde302fc182fcf0547b9f2e57bc370455be76..955b47c56ad526c42cf005d7a9cd6d3fbb841826 100644
--- a/packages/language-select/src/vpu-language-select-demo.js
+++ b/packages/language-select/src/vpu-language-select-demo.js
@@ -1,5 +1,5 @@
 import {html, LitElement} from 'lit-element';
-import {LanguageSelect} from './vpu-language-select.js';
+import {LanguageSelect} from './language-select.js';
 import * as commonUtils from 'vpu-common/utils';
 import { ScopedElementsMixin } from '@open-wc/scoped-elements';
 
diff --git a/packages/language-select/src/vpu-language-select.js b/packages/language-select/src/vpu-language-select.js
index 27cd64e182e27d9405f41003a059d00314b82c77..97dcfdf68311d285ce3ca3945392a420b47986c9 100644
--- a/packages/language-select/src/vpu-language-select.js
+++ b/packages/language-select/src/vpu-language-select.js
@@ -1,133 +1,4 @@
-import {html, css, LitElement} from 'lit-element';
-import {i18n} from './i18n.js';
-import * as commonStyles from 'vpu-common/styles';
+import * as commonUtils from 'vpu-common/utils';
+import {LanguageSelect} from './language-select.js';
 
-/**
- * Emits a vpu-language-changed event where event.detail.lang is the new selected language
- */
-export class LanguageSelect extends LitElement {
-
-    constructor() {
-        super();
-        this._lang = 'de';
-        this.languages = ['de', 'en'];
-
-        this.onExternalChange = this.onExternalChange.bind(this);
-
-        // for the i18next scanner
-        i18n.t('de');
-        i18n.t('de-action');
-        i18n.t('en');
-        i18n.t('en-action');
-    }
-
-    _getNextLanguage(lang) {
-        var index = this.languages.indexOf(lang);
-        var next = this.languages[index + 1];
-        if (typeof next === 'undefined')
-            next = this.languages[0];
-        return next;
-    }
-
-    _getPreviousLanguage(lang) {
-        var index = this.languages.indexOf(lang);
-        var prev = this.languages[index - 1];
-        if (typeof prev === 'undefined')
-            prev = this.languages[this.languages.length - 1];
-        return prev;
-    }
-
-    static get properties() {
-        return {
-            lang: {type: String},
-            next: {type: String},
-            languages: {type: Array},
-        };
-    }
-
-    set lang(value) {
-        const oldValue = this.lang;
-        const oldNext = this.next;
-        this._lang = value;
-        this.requestUpdate('lang', oldValue);
-        this.requestUpdate('next', oldNext);
-
-        if (oldValue !== value) {
-            const event = new CustomEvent("vpu-language-changed", {
-                bubbles: true,
-                composed: true,
-                detail: {'lang': value}
-            });
-            this.dispatchEvent(event);
-
-            // Unlike other cases we use the next language for the translations so that
-            // users not knowing the current language can understand it.
-            // In case of more than two this doesn't make that much sense, but for now..
-            i18n.changeLanguage(this.next);
-        }
-    }
-
-    get lang() {
-        return this._lang;
-    }
-
-    set next(value) {
-        this.lang = this._getPreviousLanguage(value);
-    }
-
-    get next() {
-        return this._getNextLanguage(this.lang);
-    }
-
-    static get styles() {
-        // language=css
-        return css`
-            ${commonStyles.getThemeCSS()}
-
-            :host {
-                display: inline-block;
-            }
-
-            a:hover {
-                background-color: var(--vpu-dark);
-                color: var(--vpu-light);
-                transition: none;
-            }
-
-            a {
-                padding: 0.3em;
-                display: inline-block;
-                text-decoration: none;
-                transition: background-color 0.15s, color 0.15s;
-                color: var(--vpu-dark);
-                border-radius: var(--vpu-border-radius);
-            }
-        `;
-    }
-
-    onExternalChange(e) {
-        this.lang = e.detail.lang
-    }
-
-    connectedCallback() {
-        super.connectedCallback();
-        window.addEventListener('vpu-language-changed', this.onExternalChange);
-    }
-
-    disconnectedCallback() {
-        document.removeEventListener('vpu-language-changed', this.onExternalChange);
-        super.disconnectedCallback();
-    }
-
-    onClick(e) {
-        e.preventDefault();
-        this.lang = this.next;
-    }
-
-    render() {
-        var linkTitle = i18n.t(this.next + '-action');
-        return html`
-            <a href="#" title="${linkTitle}" @click=${this.onClick}>${this.next.toUpperCase()}</a>
-        `;
-    }
-}
\ No newline at end of file
+commonUtils.defineCustomElement('vpu-language-select', LanguageSelect);
diff --git a/packages/language-select/test/unit.js b/packages/language-select/test/unit.js
index 92e51f10cc21b2d6b856ed17f204134cafd2d981..b79ca875a906147e1621e9016f6ea09b4f6644a4 100644
--- a/packages/language-select/test/unit.js
+++ b/packages/language-select/test/unit.js
@@ -1,10 +1,6 @@
-import {LanguageSelect} from '../src/vpu-language-select.js';
-import * as commonUtils from 'vpu-common/utils';
+import '../src/vpu-language-select.js';
 import '../src/demo.js';
 
-
-commonUtils.defineCustomElement('vpu-language-select', LanguageSelect);
-
 describe('vpu-language-select basics', () => {
   let node;
   let events = [];