MagicMirror Installation Guide - Raspberry Pi 4

Maintainer: Tony Di Bona | Updated: May 2, 2026

Prerequisites

Step 1 - Flash SD Card

Using Raspberry Pi Imager, select Raspberry Pi OS 64-bit (2026-04-21). Click the settings gear and configure:

Step 2 - First Boot Setup

sudo apt update && sudo apt upgrade -y

Step 3 - Disable Sudo Password

sudo visudo

Find this line: %sudo ALL=(ALL:ALL) ALL

Change it to:

%sudo   ALL=(ALL:ALL) NOPASSWD: ALL

Step 4 - Install Node.js 24

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

Step 5 - Install MagicMirror

cd ~
git clone https://github.com/MagicMirrorOrg/MagicMirror
cd MagicMirror
npm run install-mm
cp ~/MagicMirror/config/config.js.sample ~/MagicMirror/config/config.js

Step 6 - Configure MagicMirror Autostart

mkdir -p ~/.config/autostart
vi ~/.config/autostart/magicmirror.desktop

Add this content:

[Desktop Entry]
Type=Application
Name=MagicMirror
Exec=bash -c 'cd /home/pindari/MagicMirror && WAYLAND_DISPLAY=wayland-0 npm start'
X-GNOME-Autostart-enabled=true

Step 7 - Configure Portrait Display Rotation

vi ~/.config/autostart/randr.desktop

Add this content:

[Desktop Entry]
Type=Application
Name=Display Rotation
Exec=bash -c 'WAYLAND_DISPLAY=wayland-0 wlr-randr --output HDMI-A-1 --transform 90 >> /tmp/randr.log 2>&1'
X-GNOME-Autostart-enabled=true

Step 8 - Force 1920x1080 Resolution

The Raspberry Pi 4 may not correctly read the monitor's EDID data and fall back to a lower resolution. To force 1920x1080:

sudo vi /boot/firmware/cmdline.txt

Add video=HDMI-A-1:1920x1080@60 to the end of the existing single line, separated by a space. The file must remain a single line.

Step 9 - Reboot

sudo reboot

Step 10 - Verify Settings

Verify the display resolution and rotation:

WAYLAND_DISPLAY=wayland-0 wlr-randr

Confirm that the output shows 1920x1080 px as the current mode and Transform: 90.

Verify Node.js and MagicMirror status:

node -v && npm -v
ps aux | grep electron | grep -v grep

Step 11 - Install MMM-ImageSlideshow

cd ~/MagicMirror/modules
git clone https://github.com/AdamMoses-GitHub/MMM-ImageSlideshow.git

Step 12 - Create Photos Folder

The photos folder already exists as exampleImages inside the module. Upload photos to:

~/MagicMirror/modules/MMM-ImageSlideshow/exampleImages/

Photos should be 1040 x 614 pixels and in 16:9 aspect ratio for best results.

Step 13 - Install MMM-Todoist2

cd ~/MagicMirror/modules
git clone https://github.com/ZachR19/MMM-Todoist2.git
cd MMM-Todoist2
npm install

Step 14 - Get Todoist API Token

  1. Go to todoist.com and log in
  2. Click your profile picture → SettingsIntegrationsDeveloper
  3. Copy your API token
  4. Note your Project ID from the URL when viewing your project: https://app.todoist.com/app/project/myProject-PROJECTID

Step 15 - Configure config.js

vi ~/MagicMirror/config/config.js

Replace the entire file with:

let config = {
    address: "localhost",
    port: 8080,
    basePath: "/",
    ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
    useHttps: false,
    httpsPrivateKey: "",
    httpsCertificate: "",
    language: "en",
    locale: "en-US",
    logLevel: ["INFO", "LOG", "WARN", "ERROR"],
    timeFormat: 24,
    units: "metric",
    modules: [
        {
            module: "clock",
            position: "top_left",
            header: "Local Time",
            config: {
                timezone: "Pacific/Auckland",
                timeFormat: 12,
                showPeriod: true,
                showDate: true,
                dateFormat: "ddd, MMM D, YYYY",
                displaySeconds: false,
            }
        },
        {
            module: "clock",
            position: "top_right",
            header: "California Time",
            config: {
                timezone: "America/Los_Angeles",
                timeFormat: 12,
                showPeriod: true,
                showDate: true,
                dateFormat: "ddd, MMM D, YYYY",
                displaySeconds: false,
            }
        },
        {
            module: "MMM-ImageSlideshow",
            position: "upper_third",
            config: {
                imagePaths: ["modules/MMM-ImageSlideshow/exampleImages/"],
                slideshowSpeed: 5000,
                randomizeImageOrder: true,
                fixedImageWidth: 1040,
                fixedImageHeight: 614,
            }
        },
        {
            module: "weather",
            position: "middle_center",
            config: {
                weatherProvider: "openmeteo",
                type: "forecast",
                lat: -41.2190,
                lon: 175.4601,
                maxNumberOfDays: 7,
                units: "metric",
                showPrecipitationAmount: true,
                showPrecipitationProbability: true,
                showWindDirection: true,
                roundTemp: true,
                colored: true,
                appendLocationNameToHeader: false,
            }
        },
        {
            module: "calendar",
            position: "bottom_left",
            header: "Upcoming Events",
            config: {
                maximumEntries: 10,
                maximumNumberOfDays: 30,
                showLocation: false,
                fade: false,
                timeFormat: "dateheaders",
                appendLocationNameToHeader: false,
                calendars: [
                    {
                        url: "YOUR_GOOGLE_ICAL_URL",
                        symbol: "calendar-days",
                    }
                ],
            }
        },
        {
            module: "MMM-Todoist2",
            position: "bottom_right",
            header: "Tasks",
            config: {
                accessToken: "YOUR_TODOIST_API_TOKEN",
                maximumEntries: 60,
                updateInterval: 10*60*1000,
                fade: false,
                showProject: false,
                sortOrder: ["priority"],
                projects: ["YOUR_PROJECT_ID"],
            }
        },
    ],
};
if (typeof module !== "undefined") { module.exports = config; }

Step 16 - Configure custom.css

vi ~/MagicMirror/config/custom.css

Add this content:

:root {
  --gap-body-left: 20px;
  --gap-body-right: 20px;
}

.clock .module-header {
  font-size: 1.65em;
}

.clock .date {
  font-size: 2.55em;
}

.clock .time {
  font-size: 4.65em;
}

.weather .forecast .day {
  font-size: 2em;
}

.weather table {
  font-size: 2em;
}

.region.upper.third {
  top: calc(33% - 60px);
}

.region.middle.center {
  top: calc(65% - 120px);
}

.region.bottom.left {
  max-height: 600px;
  overflow: hidden;
}

.region.bottom.right {
  max-height: 600px;
  overflow: hidden;
}

.calendar .module-header {
  font-size: 2em;
}

.calendar .title {
  font-size: 1.5em;
}

.calendar .time {
  font-size: 1.5em;
}

.calendar .symbol {
  font-size: 1em;
}

.calendar .dateheader {
  font-size: 1.5em;
}

.MMM-Todoist2 .module-header {
  font-size: 2em;
}

.MMM-Todoist2 .title {
  font-size: 1.5em;
}

.MMM-Todoist2 .dueDate {
  font-size: 1.5em;
}

.MMM-Todoist2 .projectname {
  font-size: 1.5em;
}

Step 17 - Get Google Calendar iCal URL

  1. Go to calendar.google.com on your computer
  2. Click the three dots next to the calendar you want to display
  3. Click Settings and sharing
  4. Scroll down to Integrate calendar
  5. Copy the Secret address in iCal format — it ends in basic.ics
  6. Edit config.js and replace YOUR_GOOGLE_ICAL_URL with this URL
vi ~/MagicMirror/config/config.js

Step 18 - Reboot

sudo reboot