{"id":21894681,"url":"https://github.com/susumuota/minimal-image-viewer","last_synced_at":"2026-05-05T13:37:19.619Z","repository":{"id":65081317,"uuid":"578991719","full_name":"susumuota/minimal-image-viewer","owner":"susumuota","description":"A minimal image viewer Desktop app for macOS, Windows and Linux.","archived":false,"fork":false,"pushed_at":"2023-01-25T16:28:02.000Z","size":522,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-30T10:46:36.112Z","etag":null,"topics":["electron","electron-app","electron-forge","image-viewer","node","nodejs","react","reactjs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/susumuota.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-12-16T11:41:37.000Z","updated_at":"2023-11-25T12:28:27.000Z","dependencies_parsed_at":"2023-02-14T09:30:59.600Z","dependency_job_id":null,"html_url":"https://github.com/susumuota/minimal-image-viewer","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/susumuota/minimal-image-viewer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susumuota%2Fminimal-image-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susumuota%2Fminimal-image-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susumuota%2Fminimal-image-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susumuota%2Fminimal-image-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susumuota","download_url":"https://codeload.github.com/susumuota/minimal-image-viewer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susumuota%2Fminimal-image-viewer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32651822,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","electron-app","electron-forge","image-viewer","node","nodejs","react","reactjs","typescript"],"created_at":"2024-11-28T13:27:36.326Z","updated_at":"2026-05-05T13:37:19.591Z","avatar_url":"https://github.com/susumuota.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# minimal-image-viewer\n\n[![GitHub release (latest by date)](https://img.shields.io/github/v/release/susumuota/minimal-image-viewer)](https://github.com/susumuota/minimal-image-viewer/releases)\n[![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/susumuota/minimal-image-viewer)](https://github.com/susumuota/minimal-image-viewer)\n[![GitHub](https://img.shields.io/github/license/susumuota/minimal-image-viewer)](https://github.com/susumuota/minimal-image-viewer/blob/main/LICENSE)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/susumuota/minimal-image-viewer/build.yaml)](https://github.com/susumuota/minimal-image-viewer/actions/workflows/build.yaml)\n[![GitHub last commit](https://img.shields.io/github/last-commit/susumuota/minimal-image-viewer)](https://github.com/susumuota/minimal-image-viewer/commits)\n\nA minimal image viewer Desktop app for macOS, Windows and Linux.\n\n- minimal and simple code based on [Electron Forge](https://www.electronforge.io/)\n- pager-like key bindings (e.g. `space` key to move forward one page, `b` key to move backward one page)\n- pre-loading images to improve performance\n- macOS, Windows and Linux binaries are available\n\n## Download\n\n- https://github.com/susumuota/minimal-image-viewer/releases\n\n## Usage\n\n```\nKey bindings (similar as 'less' command)\n\no, O                                       Open image files or directories.\nr, R                                       Reload directories.\nh, H                                       Toggle this help.\ni, I                                       Toggle showing metadata as a tooltip.\nq, Q                                       Quit.\nf, j, PageDown, ArrowDown, Space, Enter    Move forward one page.\nb, k, PageUp, ArrowUp                      Move backward one page.\ng, \u003c, Home                                 Go to first page.\nG, \u003e, End                                  Go to last page.\nArrowRight                                 Increase the number of images per page.\nArrowLeft                                  Reduce the number of images per page.\n⌘+, Ctrl and +                             Zoom in.\n⌘-, Ctrl and -                             Zoom out.\n⌘0, Ctrl and 0                             Actual size.\nF12                                        Open DevTools.\n```\n\n## Source code\n\n- https://github.com/susumuota/minimal-image-viewer\n\n## TODO\n\n- [x] Windows binary\n- [x] Linux binary\n- [x] show PNG information (tEXt chunk)\n- [ ] improve app startup time (V8 snapshots?)\n- [ ] watch directory change (chokidar?)\n\n## For developers\n\nHere's an initial log to create an Electron app with Webpack, TypeScript, React and GitHub.\n\n### Create a new Electron project with Webpack and Typescript\n\n- https://www.electronforge.io/#using-templates\n- https://www.electronforge.io/templates/typescript-+-webpack-template\n\n```sh\nnode -v  # v18.12.1\nnpm -v   # 8.19.2\nnpm init electron-app@latest minimal-image-viewer -- --template=webpack-typescript\ncd minimal-image-viewer\n```\n\nTest it.\n\n```sh\nnpm run start\nnpm run make\nopen out/minimal-image-viewer-darwin-x64/minimal-image-viewer.app\n```\n\nOK.\n\n### Update TypeScript\n\nTypeScript is a bit outdated so renew it.\n\n```sh\nnpm outdated\nnpm install --save-dev typescript@latest\n```\n\nAlso, `tsconfig.json` looks a bit old so renew it.\n\nBased on [Node LTS + ESM + Strictest](https://github.com/tsconfig/bases#node-lts--esm--strictest-tsconfigjson) settings,\n\n```sh\nnpm install --save-dev @tsconfig/node-lts-strictest-esm\nrm tsconfig.json\n```\n\nCreate a new `tsconfig.json` file. Add `dom` (for `window`) and `react-jsx` (for `jsx`).\n\n- `tsconfig.json`\n\n```json\n{\n  \"extends\": \"@tsconfig/node-lts-strictest-esm/tsconfig.json\",\n  \"compilerOptions\": {\n    \"lib\": [\n      \"es2022\",\n      \"dom\",\n    ],\n    \"module\": \"commonjs\",\n    \"jsx\": \"react-jsx\",\n  },\n}\n```\n\nConfirm settings.\n\n```sh\nnpx tsc --showConfig\n```\n\nTest it again.\n\n```sh\nnpm run start\n```\n\nOK.\n\n### Add React\n\n- https://www.electronforge.io/guides/framework-integration/react-with-typescript\n- https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis\n\nInstall React.\n\n```sh\nnpm install --save react react-dom\nnpm install --save-dev @types/react @types/react-dom\n```\n\nAdd some template files.\n\n- `src/index.html`\n\nAdd this to the inside of `body`.\n\n```html\n    \u003cdiv id=\"app\" /\u003e\n```\n\n- `src/app.tsx`\n\nCreate a new file `src/app.tsx`.\n\n```tsx\nimport { createRoot } from 'react-dom/client';\n\nfunction render() {\n  const container = document.getElementById('app');\n  if (container) {\n    const root = createRoot(container);\n    root.render(\u003ch2\u003eHello from React!\u003c/h2\u003e);\n  }\n}\n\nrender();\n```\n\n- `src/renderer.ts`\n\nAdd this to the end of the existing file.\n\n```ts\nimport './app';\n```\n\nTest it.\n\n```sh\nnpm run start\n```\n\nOK.\n\n### Choose License and create README.md\n\n- https://choosealicense.com/\n\n```sh\ntouch LICENSE     # create a file and copy license text from site. e.g. https://choosealicense.com/licenses/mit/\ntouch README.md   # also create a README file\n```\n\nDon't forget to change `license` field on `package.json`.\n\n- `package.json`\n\n```json\n  \"license\": \"MIT\",\n```\n\n### Create a GitHub repository\n\nCommit. No need to run `git init`.\n\n```sh\ngit status\ngit add --all\ngit status\ngit commit -m \"initial commit.\"\n```\n\nGo to https://github.com/ and create a new repository `minimal-image-viewer`.\n\n```sh\ngit remote add origin git@github.com:susumuota/minimal-image-viewer.git\ngit branch -M main\ngit push -u origin main\n```\n\n### Add GitHub publisher\n\n- https://www.electronforge.io/config/publishers/github\n- https://js.electronforge.io/interfaces/_electron_forge_publisher_github.PublisherGitHubConfig.html\n- https://github.com/electron/forge/blob/main/packages/publisher/github/src/PublisherGithub.ts\n- https://github.com/electron/forge/blob/main/packages/publisher/github/src/Config.ts\n\n```sh\nnpm install --save-dev @electron-forge/publisher-github\n```\n\n- `force.config.ts`\n\nAdd this import.\n\n```ts\nimport { PublisherGithub } from '@electron-forge/publisher-github';\n```\n\nAdd this after `plugins`.\n\n```ts\n  publishers: [\n    new PublisherGithub({\n      repository: {\n        name: 'minimal-image-viewer',\n        owner: 'susumuota',\n      },\n      prerelease: true,\n      draft: true,\n    }),\n  ],\n```\n\nCreate a github token.\n\n**You can skip this token generation if you only use GitHub Actions to publish binaries**\n\n- https://github.com/settings/personal-access-tokens/new\n- https://docs.github.com/en/rest/overview/permissions-required-for-fine-grained-personal-access-tokens\n- https://docs.github.com/en/rest/releases/releases#create-a-release\n\nGo to https://github.com/settings/personal-access-tokens/new\n\n- Token name: `publish minimal-image-viewer`\n- Description: `A token to publish minimal-image-viewer.`\n- Repository access\n  - `Only select repositories`\n    - `Select repositories`\n      - `susumuota/minimal-image-viewer`\n- Permissions\n  - `Repository permissions`\n    - Contents\n      - `Read and write`\n- `Generate token`\n\nCopy the token to `~/.zshrc`.\n\n```sh\nexport GITHUB_TOKEN=\"(secret info)\"\n```\n\nReopen terminal or `exec $SHELL`.\n\nPublish.\n\n```sh\nnpm run publish\n```\n\nIt might take a few minutes.\n\nGo to https://github.com/susumuota/minimal-image-viewer/releases\n\nClick `Assets` and download `minimal-image-viewer-darwin-x64-1.0.0.zip`.\n\nUnzip.\n\nRight click `minimal-image-viewer.app` and `Open`.\n\nOK.\n\n### Setup GitHub Actions to build binaries for macOS, Windows and Linux\n\n- https://dev.to/erikhofer/build-and-publish-a-multi-platform-electron-app-on-github-3lnd\n\nCreate a `build.yaml` to automatically build binaries on push to the main branch and pull requests.\n\n- `.github/workflows/build.yaml`\n\n```yaml\nname: Build\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest, macos-latest]\n    steps:\n    - uses: actions/checkout@v3\n    - uses: actions/setup-node@v3\n      with:\n        node-version: 18.12.1\n    - run: npm ci\n    - run: npm run make\n```\n\nTest it.\n\n```sh\ngit add ...\ngit commit ...\ngit push origin main\n```\n\nCreate a `release.yaml` to automatically build binaries on push tags (e.g. `v1.0.0`).\n\n- `.github/workflows/release.yaml`\n\n```yaml\nname: Release\n\non:\n  push:\n    tags:\n      - v[0-9]+.[0-9]+.[0-9]+\n\njobs:\n  release:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest, macos-latest]\n    steps:\n    - uses: actions/checkout@v3\n    - uses: actions/setup-node@v3\n      with:\n        node-version: 18.12.1\n    - run: npm ci\n    - run: npm run publish\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nTest it.\n\n```sh\ngit tag v1.0.0\ngit push origin v1.0.0\n```\n\nGo to https://github.com/susumuota/minimal-image-viewer/releases\n\nDownload and test packages.\n\nDone.\n\n## License\n\nMIT License. See LICENSE file.\n\n## Author\n\nSusumu OTA\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusumuota%2Fminimal-image-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusumuota%2Fminimal-image-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusumuota%2Fminimal-image-viewer/lists"}