Element Desktop with Giphy GIF picker support
  • TypeScript 77.5%
  • JavaScript 19.8%
  • Shell 2.1%
  • Dockerfile 0.5%
  • Batchfile 0.1%
Find a file
EmitLinks 9127fcf12d
Some checks failed
build_macos.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (push) Failing after 0s
build_prepare.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (push) Failing after 0s
build_windows.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (push) Failing after 0s
Build and Deploy / prepare (release) Blocked by required conditions
Build and Deploy / Trigger Pro pipeline (release) Blocked by required conditions
Build and Deploy / Windows arm64 (release) Blocked by required conditions
Build and Deploy / Windows x64 (release) Blocked by required conditions
Build and Deploy / macOS (release) Blocked by required conditions
Build and Deploy / Linux amd64 (sqlcipher static) (release) Blocked by required conditions
Build and Deploy / Linux arm64 (sqlcipher static) (release) Blocked by required conditions
Build and Deploy / Deploy (dry-run) (release) Blocked by required conditions
Build and Deploy / Deploy builds to ESS (release) Blocked by required conditions
Build and Deploy / Prepare (release) Waiting to run
build_macos.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (release) Failing after 0s
build_prepare.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (release) Failing after 0s
build_windows.yaml / Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) (release) Failing after 0s
Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url)
2026-09-19 14:53:18 +02:00
.github v1.12.13 2026-03-24 11:49:01 +00:00
.husky v1.12.13 2026-03-24 11:49:01 +00:00
build v1.12.13 2026-03-24 11:49:01 +00:00
dockerbuild v1.12.13 2026-03-24 11:49:01 +00:00
docs v1.12.13 2026-03-24 11:49:01 +00:00
element.io v1.12.13 2026-03-24 11:49:01 +00:00
hak v1.12.13 2026-03-24 11:49:01 +00:00
patches v1.12.13 2026-03-24 11:49:01 +00:00
playwright v1.12.13 2026-03-24 11:49:01 +00:00
scripts Giphy: fix MSC3885 v2 base64 encodings (iv + sha256 -> standard base64 no-pad; key.k stays base64url) 2026-09-19 14:53:18 +02:00
src v1.12.13 2026-03-24 11:49:01 +00:00
.eslintrc.cjs v1.12.13 2026-03-24 11:49:01 +00:00
.gitignore v1.12.13 2026-03-24 11:49:01 +00:00
.lintstagedrc v1.12.13 2026-03-24 11:49:01 +00:00
.node-version v1.12.13 2026-03-24 11:49:01 +00:00
.prettierignore v1.12.13 2026-03-24 11:49:01 +00:00
.prettierrc.cjs v1.12.13 2026-03-24 11:49:01 +00:00
babel.config.cjs v1.12.13 2026-03-24 11:49:01 +00:00
CHANGELOG.md v1.12.13 2026-03-24 11:49:01 +00:00
CONTRIBUTING.md v1.12.13 2026-03-24 11:49:01 +00:00
electron-builder.ts v1.12.13 2026-03-24 11:49:01 +00:00
knip.ts v1.12.13 2026-03-24 11:49:01 +00:00
LICENSE-AGPL-3.0 v1.12.13 2026-03-24 11:49:01 +00:00
LICENSE-COMMERCIAL v1.12.13 2026-03-24 11:49:01 +00:00
LICENSE-GPL-3.0 v1.12.13 2026-03-24 11:49:01 +00:00
localazy.json v1.12.13 2026-03-24 11:49:01 +00:00
package.json Giphy GIF support: Discord-style composer button, E2EE-safe send, reproducible build 2026-09-17 12:00:00 +00:00
playwright.config.ts v1.12.13 2026-03-24 11:49:01 +00:00
pnpm-lock.yaml Giphy GIF support: Discord-style composer button, E2EE-safe send, reproducible build 2026-09-17 12:00:00 +00:00
pnpm-workspace.yaml v1.12.13 2026-03-24 11:49:01 +00:00
README.md Giphy GIF support: Discord-style composer button, E2EE-safe send, reproducible build 2026-09-17 12:00:00 +00:00
tsconfig.json v1.12.13 2026-03-24 11:49:01 +00:00

Build Static Analysis Localazy Quality Gate Status Vulnerabilities Bugs

Element Desktop

Element Desktop is a Matrix client for desktop platforms with Element Web at its core.

First Steps

Before you do anything else, fetch the dependencies:

pnpm install

Fetching Element

Since this package is just the Electron wrapper for Element Web, it doesn't contain any of the Element Web code, so the first step is to get a working copy of Element Web. There are a few ways of doing this:

# Fetch the prebuilt release Element package from the element-web GitHub releases page. The version
# fetched will be the same as the local element-desktop package.
# We're explicitly asking for no config, so the packaged Element will have no config.json.
pnpm run fetch --noverify --cfgdir ""

...or if you'd like to use GPG to verify the downloaded package:

# Fetch the Element public key from the element.io web server over a secure connection and import
# it into your local GPG keychain (you'll need GPG installed). You only need to to do this
# once.
pnpm run fetch --importkey
# Fetch the package and verify the signature
pnpm run fetch --cfgdir ""

...or either of the above, but fetching a specific version of Element:

# Fetch the prebuilt release Element package from the element-web GitHub releases page. The version
# fetched will be the same as the local element-desktop package.
pnpm run fetch --noverify --cfgdir "" v1.5.6

If you only want to run the app locally and don't need to build packages, you can provide the webapp directory directly:

# Assuming you've checked out and built a copy of element-web in ../element-web.
# Note that you will not be able to `pnpm build` after this, but `pnpm start`
# will work fine.
ln -s ../element-web/webapp ./

[TODO: add support for fetching develop builds, arbitrary URLs and arbitrary paths]

Giphy GIF Support (this fork)

This fork adds a Discord-style Giphy GIF picker to Element Desktop. A compact control appears inside the message composer (next to the other compose buttons) — not a floating overlay. Selecting a GIF sends it into the current Matrix room through the real Matrix client send path as an m.image message, so it works in E2EE rooms (the bytes are uploaded via client.uploadContent and only the resulting mxc:// URI is sent).

  • Script: scripts/giphy-inject.js — self-contained IIFE, runs in the webview.
  • Injector: scripts/inject-webapp.ts — copies the script into bundles/<hash>/ inside webapp.asar and patches index.html to load it. Wired into the build chain: pnpm fetchfetch-package.tsgen-config.cjsinject-webapp.ts.
  • Config: scripts/gen-config.cjs writes deploys/.../config.json from the upstream element.io/release/config.json (with update_base_url removed). Without a root config.json the webapp throws invalid_configuration_no_server at startup.

Building from a fresh clone

pnpm install
pnpm run fetch      # fetches Element Web, writes config.json, injects Giphy
pnpm run build      # build:ts + build:res + electron-builder

The Giphy API key is baked in as a default (overridable) in scripts/giphy-inject.js. Giphy's anonymous keys are dead (401); a real key is required. Both the Giphy API and its media CDN send access-control-allow-origin:*, so the picker and the cross-origin GIF byte fetch work from the webapp.

Building

Native Build

TODO: List native pre-requisites

Optionally, build the native modules, which include support for searching in encrypted rooms and secure storage. Skipping this step is fine, you just won't have those features.

Then, run

pnpm run build

This will do a couple of things:

  • Run the setversion script to set the local package version to match whatever version of Element you installed above.
  • Run electron-builder to build a package. The package built will match the operating system you're running the build process on.

Docker

Alternatively, you can also build using docker, which will always produce the linux package:

# Run this once to make the docker image
pnpm run docker:setup

pnpm run docker:install
# if you want to build the native modules (this will take a while)
pnpm run docker:build:native
pnpm run docker:build

After running, the packages should be in dist/.

Starting

If you'd just like to run the electron app locally for development:

pnpm start

Config

If you'd like the packaged Element to have a configuration file, you can create a config directory and place config.json in there, then specify this directory with the --cfgdir option to pnpm run fetch, eg:

mkdir myconfig
cp /path/to/my/config.json myconfig/
pnpm run fetch --cfgdir myconfig

The config dir for the official Element app is in element.io. If you use this, your app will auto-update itself using builds from element.io.

Profiles

To run multiple instances of the desktop app for different accounts, you can launch the executable with the --profile argument followed by a unique identifier, e.g element-desktop --profile Work for it to run a separate profile and not interfere with the default one.

Alternatively, a custom location for the profile data can be specified using the --profile-dir flag followed by the desired path.

User-specified config.json

  • %APPDATA%\$NAME\config.json on Windows
  • $XDG_CONFIG_HOME/$NAME/config.json or ~/.config/$NAME/config.json on Linux
  • ~/Library/Application Support/$NAME/config.json on macOS

In the paths above, $NAME is typically Element, unless you use --profile $PROFILE in which case it becomes Element-$PROFILE, or it is using one of the above created by a pre-1.7 install, in which case it will be Riot or Riot-$PROFILE.

You may also specify a different path entirely for the config.json file by providing the --config $YOUR_CONFIG_JSON_FILE to the process, or via the ELEMENT_DESKTOP_CONFIG_JSON environment variable.

Translations

To add a new translation, head to the translating doc.

For a developer guide, see the translating dev doc.

Report bugs & give feedback

If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.

To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it. Please note that this issue tracker is associated with the element-web repo, but is also applied to the code in this repo as well.

Copyright (c) 2016-2017 OpenMarket Ltd

Copyright (c) 2017 Vector Creations Ltd

Copyright (c) 2017-2025 New Vector Ltd

This software is multi licensed by New Vector Ltd (Element). It can be used either:

(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR

(2) for free under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR

(3) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to). Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.