I Built a Raspberry Pi Magic Mirror Using MagicMirror². Here’s What Actually Worked

How to Build a Raspberry Pi Magic Mirror With MagicMirror²

A Raspberry Pi Magic Mirror is a smart mirror built using a Raspberry Pi, a display, and two-way mirror glass, running MagicMirror² software to show information like time, weather, and calendars.

The display shows through the mirror surface so you can see the time, weather, calendar, and headlines while the rest stays reflective. It looks fancy, but it’s basically a screen hiding behind glass.

The software most people use is MagicMirror², an open-source project created by Michael Teeuw and maintained on GitHub. MagicMirror² runs on Node.js, installs dependencies with npm, and renders the interface with Electron. You configure what appears on-screen by editing one file: config.js. If you can follow steps and copy commands carefully, you can build this.

This guide aims for a mirror that is stable and useful, not a fragile science project you “fix” every weekend.

What You’re Building

A working MagicMirror build has four main pieces:

  1. Raspberry Pi OS on a microSD card
  2. MagicMirror² installed from GitHub
  3. A display connected over HDMI
  4. A two-way mirror mounted in front of the display

Once installed, MagicMirror can auto-start at boot using PM2, a Node process manager. That way, if power drops or the Pi reboots, the mirror comes back on by itself.

How MagicMirror² Works

MagicMirror² is an application. It is not an operating system. It runs on Raspberry Pi OS and uses Electron to draw a full-screen interface.

Key idea: everything you see is a module.

  • Clock is a module.
  • Calendar is a module.
  • Weather is a module.
  • News feed is a module.

Modules render based on config.js. If config.js has a syntax error, the interface can fail to load. If one third-party module crashes hard, it can take down the interface. That’s why this guide pushes a simple habit: change one thing at a time, then test.

Raspberry Pi Compatibility and Requirements

You can run MagicMirror² on several Raspberry Pi models, but not all of them feel good.

Raspberry Pi (What Actually Matters)

For a Magic Mirror build, the Raspberry Pi 4 is the most practical option. The key factors that affect performance are RAM amount and power stability, not brand variants or accessories.

What to look for:

  • Raspberry Pi 4 Model B
  • At least 2GB RAM (4GB gives more headroom)
  • Genuine board, not a clone
  • Separate power supply rather than bundled cheap chargers

Many builders use standard Raspberry Pi 4 boards available through common retailers. As long as the board is authentic and paired with a proper power supply, performance differences between sellers are negligible.

RP$ 4gb

Raspberry Pi 4 Model B 2019 Quad Core 64 Bit WiFi Bluetooth (4GB)

  • Broadcom BCM2711, quad-core Cortex-A72 (ARM v8) 64-bit SoC @ 1. 5GHz—4GB LPDDR4-2400 SDRAM
  • 2. 4 GHz and 5. 0 GHz IEEE 802. 11B/g/n/ac Wireless LAN, Bluetooth 5. 0, double-true Gigabit Ethernet
  • 2 × USB 3. 0 ports, 2 x USB 2. 0 Ports—2 × micro HDMI ports supporting up to 4Kp60 video resolution
  • 2-lane MIPI DSI/CSI ports for camera and display–4-pole stereo audio and composite video port–Micro SD card slot for loading operating system and data storage
RP4PS

5V 3A USB Type C Adapter for Raspberry Pi 4 Model B Power Supply Cord with ON/Off Switch

  • [Compatibility]: Fit for Raspberry Pi 4, Pi 4 Model B.
  • [Power Specs]: Input 100V-240V 50/60Hz; Output: 5V 3A.
  • [Plug Type]: Type-C, USB-C plug. Product cable length 3.3 feet, with ON/Off Switch Design.
  • [Safety Smart]: Built-in emergency protection mechanism with short circuit, over current, over voltage, over temperature protection.

Works but slower

  • Raspberry Pi 3B / 3B+

Not recommended

  • Raspberry Pi Zero / Zero 2 W

Electron behaves like a browser running full-screen all the time. Browsers like RAM. Underpowered boards can run it, but you’ll see longer boot times, more stutter, and more pain once you add modules.

Raspberry Pi OS

  • Raspberry Pi OS Lite (64-bit) is best for a long-running mirror.
  • Raspberry Pi OS with Desktop is fine for first setup, but it uses more memory.

Power supply matters

Use a 5V 3A USB-C power supply intended for Raspberry Pi 4. Cheap chargers cause undervoltage and weird behavior like random restarts or slowdowns. People blame MagicMirror for this, but it’s usually power.

Storage

  • microSD card: 16GB minimum, Class 10 or better

Cheap cards fail quietly. Your install “works” until it doesn’t, then you lose hours.

Hardware Checklist

Core hardware

  • Raspberry Pi 4
  • microSD card (16GB+)
  • 5V 3A power supply (USB-C for Pi 4)
  • HDMI monitor or display (16–24 inches is the sweet spot)
  • Two-way mirror (acrylic or glass)
  • Frame/enclosure (wood, deep picture frame, custom box frame)
  • HDMI cable
  • Keyboard/mouse for initial setup (optional if headless)
  • Wi-Fi or Ethernet

Optional upgrades

  • PIR motion sensor (HC-SR501 is common) using GPIO
  • Heat sinks or small fan
  • USB microphone (for voice modules)
  • USB camera (for face recognition and OpenCV modules)
  • Ethernet cable (more stable than Wi-Fi)

Acrylic vs Glass Two-Way Mirror

Both work. The choice is mostly about durability and ease.

Acrylic

  • Easy to cut
  • Lightweight
  • Less likely to shatter
  • Scratches easily and needs gentle cleaning

Glass

  • Better reflection quality
  • More durable surface
  • Heavier and can crack if mishandled
  • Harder to cut without proper tools

For first builds, acrylic is fine. For “this is going in my house for years,” glass is nicer if you can mount it safely.

The parts below are common choices for MagicMirror² builds. The exact seller matters less than meeting these specifications.

Hardware Buying Guide (What to Look For and Why)

ComponentWhat Actually MattersCommon Choice for This BuildAmazon Link
Raspberry PiRAM amount and power stability matter more than brand or seller. The Pi 4 handles MagicMirror² smoothly without lag.Raspberry Pi 4 Model B (2GB or 4GB RAM)[Check current price]
Power SupplyUndervoltage causes random crashes and throttling. Many issues blamed on software are power-related.Official 5V 3A USB-C Raspberry Pi power supply[Check availability]
microSD CardSpeed and reliability matter more than capacity. Cheap cards corrupt silently.16GB–32GB Class 10 microSD from a known brand[View options]
MonitorBrightness matters more than resolution. A dim screen behind a mirror looks washed out.16–24 inch 1080p HDMI monitor (used or new)[Browse compatible monitors]
Two-Way Mirror (Acrylic)Easier to cut and lighter. Works well for first builds and wall mounting.Acrylic two-way mirror sheet cut to screen size[See sizes]
Two-Way Mirror (Glass)Better reflection quality and durability. Heavier and harder to cut.Glass two-way mirror panel (pre-cut if possible)[Check options]
Frame / EnclosureDepth and airflow matter more than looks. Shallow frames trap heat.Deep picture frame or simple wooden box frame[See frame materials]
HDMI CableLength and flexibility matter more than version numbers.Standard HDMI cable (short length preferred)[Check compatibility]
PIR Motion SensorSimple presence detection saves power and extends monitor life.HC-SR501 PIR motion sensor (GPIO-compatible)[View sensor]
Cooling (Optional)Enclosed builds benefit from basic airflow. No need for aggressive cooling.Small heat sink set or low-noise fan[View cooling options]
Microphone (Optional)Required only for voice modules. USB is simplest.Basic USB microphone (no drivers required)[See microphones]
Camera (Optional)Needed for facial recognition modules using OpenCV.USB webcam with Linux support[Browse cameras]

Software You’ll Install

  • Raspberry Pi OS
  • Git, curl
  • Node.js and npm (Node 18 LTS is a safe baseline for Raspberry Pi OS)
  • MagicMirror² from GitHub
  • PM2 for auto-start and restarts
  • A text editor (Nano is fine)

Install Raspberry Pi OS

Use Raspberry Pi Imager (or Balena Etcher) to flash your microSD card.

Headless setup (no monitor/keyboard)

If you plan to SSH in:

  1. After flashing, open the boot partition on the SD card.
  2. Create an empty file named ssh (no extension).
  3. Add Wi-Fi config if needed (many people use a wpa_supplicant.conf file, depending on OS image and setup method).

If you’re using Raspberry Pi Imager, you can often set:

  • hostname
  • Wi-Fi SSID/password
  • enable SSH
  • user/password
    inside the imager options. That is usually the cleanest route.

First boot basics

Once booted, log in and run:

sudo apt update && sudo apt upgrade -y

Then set locale/timezone:

sudo raspi-config

Also, change your password:

passwd

Yes, it’s your house. Still, don’t leave default credentials on a networked device.

Install Node.js and npm

MagicMirror² requires Node.js. On Raspberry Pi OS, Node 18 LTS is a common stable choice.

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

Verify versions:

node -v
npm -v

If Node is missing, stop here and fix that first. Almost every “MagicMirror won’t install” problem starts with Node issues.

Installing MagicMirror² From GitHub

Clone the repo and install dependencies:

cd ~
git clone https://github.com/MichMich/MagicMirror
cd MagicMirror
npm install

This can take a while. A Pi 4 is faster than a Pi 3. If it looks “stuck,” give it time unless you see clear errors.

Create your config file from the sample:

cp config/config.js.sample config/config.js

Start MagicMirror:

npm start

If you have a monitor connected, the MagicMirror interface should appear. If you’re headless, you’re mainly confirming the process runs without crashing.

Stop it with:

  • CTRL + C

Common first-run notes

  • Weather may be blank until configured.
  • Calendar may show nothing until you add an ICS feed.
  • That’s normal at this stage.

Auto-Starting MagicMirror² With PM2

PM2 is the tool that turns this into an appliance. It starts MagicMirror at boot, restarts it if it crashes, and gives you logs.

Install PM2:

sudo npm install -g pm2

Start MagicMirror using the provided config:

pm2 start ~/MagicMirror/installers/pm2_MagicMirror.json

Save the process list:

pm2 save

Enable PM2 at boot:

pm2 startup

PM2 prints a command. Copy and run it exactly.

Reboot:

sudo reboot

After reboot, check:

pm2 list

If it’s online, you’re set.

Helpful PM2 commands:

pm2 logs
pm2 restart mm
pm2 stop mm
pm2 start mm

Building the Mirror Frame and Assembly

This is the physical part. Keep it simple.

Choose a monitor

  • 16–24 inches is easiest to frame
  • 1080p is enough
  • make sure brightness is decent (a dim monitor behind a mirror looks sad)

Removing the bezel can slim the build, but it’s optional. If you do it, be careful. Some monitors use their casing for structural support.

Frame requirements

The frame must:

  • hold the mirror flat
  • keep the monitor aligned behind it
  • allow airflow for the Pi and monitor

A sealed box looks clean but traps heat. Vent holes, a gap, or a small fan solves most issues.

Mount the Raspberry Pi

Mount the Pi behind the monitor using:

  • adhesive Velcro
  • zip ties
  • small screw mounts

Keep it:

  • close to HDMI
  • accessible for the microSD card
  • away from pinched cables

Cable routing

Route and secure:

  • Pi power cable
  • monitor power cable
  • HDMI cable

Cable clips and zip ties are cheap. Use them. Loose cables become “mystery failures” later.

Final assembly order

  1. Test the monitor and Pi on a table first.
  2. Install the mirror into the frame.
  3. Mount the monitor behind it.
  4. Attach the Pi.
  5. Route cables.
  6. Test again before sealing the back.

If it’s slightly crooked, that’s life. You’ll notice it. Other people won’t.

Configuring MagicMirror² Modules

Everything lives in:

~/MagicMirror/config/config.js

Open it:

nano ~/MagicMirror/config/config.js

After edits, restart:

pm2 restart mm

If you get a black screen, check config syntax:

cd ~/MagicMirror
npm run config:check

How module config works

MagicMirror uses a modules: [] array. Each module entry includes:

  • module name
  • position
  • optional config

Positions you’ll actually use:

  • top_left
  • top_right
  • bottom_left
  • bottom_right
  • bottom_bar
  • middle_center

Core module examples (copy-ready)

Clock

{
  module: "clock",
  position: "top_left",
  config: {
    timeFormat: 12,
    showSeconds: false
  }
},

Calendar (ICS feed)
MagicMirror’s calendar module reads ICS URLs. Google Calendar can provide a private ICS link.

{
  module: "calendar",
  position: "top_left",
  config: {
    calendars: [
      {
        url: "YOUR_PRIVATE_ICS_URL",
        symbol: "calendar"
      }
    ]
  }
},

Weather (OpenWeatherMap)
Weather commonly uses OpenWeatherMap. You’ll need an API key and location ID.

{
  module: "weather",
  position: "top_right",
  config: {
    location: "New York",
    locationID: "5128581",
    apiKey: "YOUR_API_KEY"
  }
},

If weather stays blank, it’s usually:

  • wrong API key
  • wrong location ID
  • network issues

Newsfeed (RSS)

{
  module: "newsfeed",
  position: "bottom_bar",
  config: {
    feeds: [
      { title: "BBC", url: "http://feeds.bbci.co.uk/news/rss.xml" }
    ],
    showSourceTitle: true,
    showPublishDate: true
  }
},

Compliments

{
  module: "compliments",
  position: "lower_third",
  config: {
    compliments: {
      anytime: [
        "You made coffee. That counts as productivity."
      ]
    }
  }
},

Config rules that prevent pain

  • Change one thing at a time.
  • Restart and confirm it works.
  • Back up config.js and custom.css before big changes.

Adding Third-Party Modules Safely

Most third-party modules live on GitHub and install like this:

  1. Clone into the modules folder:
cd ~/MagicMirror/modules
git clone https://github.com/username/module-name.git
  1. Read the README
    Some modules need:
cd module-name
npm install
  1. Add the module block to config.js
  2. Restart:
pm2 restart mm

How to avoid breaking everything

  • Add one module at a time.
  • If the screen goes black, comment out the last module you added and restart.
  • If a module hasn’t been updated in years, expect problems with newer Node/Electron combos.

To remove a broken module:

rm -rf ~/MagicMirror/modules/module-name

Styling With custom.css

Custom styling lives here:

~/MagicMirror/css/custom.css

Create or edit it:

nano ~/MagicMirror/css/custom.css

A few useful tweaks:

Increase base font size:

body { font-size: 20px; }

Add padding to regions:

.region { padding: 20px; }

Reduce secondary text brightness:

.dimmed { opacity: 0.6; }

Restart after changes:

pm2 restart mm

Mirrors reduce contrast. Bigger text and clean spacing beat fancy design every time.

Smart Features (Optional)

PIR motion sensor (GPIO)

A PIR sensor can turn the display off when nobody is there and on when someone walks up. It connects to the Raspberry Pi GPIO pins and can trigger HDMI power control.

Common approach:

  • PIR input triggers a script
  • script calls HDMI on/off commands
  • MagicMirror keeps running, the display sleeps

This upgrade improves daily use more than most “cool” features.

Voice control

Voice modules require:

  • USB microphone
  • a compatible module
  • setup time and tuning

It’s workable. It’s also easy to get annoyed by false triggers, so don’t make it your first upgrade.

Facial recognition (OpenCV)

Facial recognition modules often rely on OpenCV and a USB camera. They can show different modules for different users. They also depend heavily on lighting and camera quality. If you want this, plan for tinkering.

Smart home integration (MQTT, Homebridge)

Many smart home displays use MQTT or bridge platforms. If you already run a smart home stack, a mirror can display device status, sensor data, and alerts.

Performance, Stability, and Security

Heat control

Check temperature:

vcgencmd measure_temp

If temps run high:

  • add heat sinks
  • add airflow
  • add a small fan
  • avoid sealed enclosures

Network reliability

Ethernet is more stable than Wi-Fi. If you use Wi-Fi, use 5GHz when possible and keep the Pi away from metal and tight enclosures that block signal.

Security basics

  • change default password
  • keep SSH on your local network
  • don’t expose the Pi directly to the internet

This is not paranoia. This is basic “don’t be lazy” hygiene.

Troubleshooting

Black screen

Most common cause: config.js syntax error.

Check:

cd ~/MagicMirror
npm run config:check
pm2 logs

Fix the last change you made, restart, and confirm.

Modules not loading

  • third-party module dependency missing
  • API key missing or wrong
  • module folder name mismatch

Disable the new module first, restart, then re-add it correctly.

PM2 says online but display is blank

PM2 can show the process running even if Electron isn’t rendering correctly. Check logs:

pm2 logs

HDMI “no signal”

  • wrong input selected
  • loose cable
  • Pi not detecting display

If you need to force HDMI output, update boot config (varies by OS version), then reboot. This is hardware-specific enough that you should confirm your current Raspberry Pi OS boot configuration path before editing.

Maintenance

Update MagicMirror² occasionally:

cd ~/MagicMirror
git pull
npm install
pm2 restart mm

Back up these files:

  • ~/MagicMirror/config/config.js
  • ~/MagicMirror/css/custom.css

If you make frequent changes, put those files into a private GitHub repo so you can roll back fast.

FAQ

Can I use a Raspberry Pi 3?
Yes. Expect slower performance, especially with more modules.

Do I need to know how to code?
No. You need to edit config files carefully.

What happens if power goes out?
The Pi reboots and PM2 starts MagicMirror automatically if configured.

Is it safe to run 24/7?
Yes, if you manage heat and use a proper power supply.

Final Notes

If you want a mirror that stays reliable: keep the build simple, keep the config clean, and add features slowly. That’s the boring advice that works.

References

Was this helpful?

Yes
No
Thanks for your feedback!