{"id":13683235,"url":"https://github.com/BearToCode/mismerge","last_synced_at":"2025-04-30T12:34:01.686Z","repository":{"id":199520352,"uuid":"688177126","full_name":"BearToCode/mismerge","owner":"BearToCode","description":"A modern merge editor for the Web","archived":false,"fork":false,"pushed_at":"2024-08-19T16:10:36.000Z","size":3922,"stargazers_count":57,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-21T04:26:16.369Z","etag":null,"topics":["diff","editor","merge","merge-editor","mismerge","svelte","web-merge-editor"],"latest_commit_sha":null,"homepage":"https://beartocode.github.io/mismerge/","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/BearToCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"beartocode","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2023-09-06T20:08:06.000Z","updated_at":"2025-04-18T03:16:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"1e2c3607-fdd6-4b50-8494-24b587a21ec7","html_url":"https://github.com/BearToCode/mismerge","commit_stats":{"total_commits":176,"total_committers":5,"mean_commits":35.2,"dds":0.03409090909090906,"last_synced_commit":"f28742d8ebb2a36aca941fb6e0517325f17e5e3c"},"previous_names":["beartocode/mismerge"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BearToCode%2Fmismerge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BearToCode%2Fmismerge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BearToCode%2Fmismerge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BearToCode%2Fmismerge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BearToCode","download_url":"https://codeload.github.com/BearToCode/mismerge/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250738309,"owners_count":21479164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["diff","editor","merge","merge-editor","mismerge","svelte","web-merge-editor"],"created_at":"2024-08-02T13:02:04.967Z","updated_at":"2025-04-30T12:34:01.150Z","avatar_url":"https://github.com/BearToCode.png","language":"TypeScript","funding_links":["https://ko-fi.com/beartocode"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"right\"\u003e\n\u003ca href=\"https://www.npmjs.com/package/@mismerge/core\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/%40mismerge%2Fcore?color=6a7fec\u0026labelColor=171d27\u0026logo=npm\u0026logoColor=white\" alt=\"npm\"\u003e\u003c/a\u003e\n\u003ca href=\"https://bundlephobia.com/package/@mismerge/core\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/min/%40mismerge%2Fcore?color=6a7fec\u0026labelColor=171d27\u0026logo=javascript\u0026logoColor=white\" alt=\"bundle\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/BearToCode/mismerge/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/beartocode/mismerge?color=6a7fec\u0026labelColor=171d27\u0026logo=git\u0026logoColor=white\" alt=\"license\"\u003e\u003c/a\u003e\n\u003ca href=\"http://beartocode.github.io/mismerge/\"\u003e\u003cimg src=\"https://img.shields.io/badge/available-red?label=demo\u0026color=6a7fec\u0026labelColor=171d27\u0026logo=svelte\u0026logoColor=white\" alt=\"demo\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n\u003cimg alt=\"banner\" src=\"https://raw.githubusercontent.com/BearToCode/mismerge/master/images/banner-light.png#gh-light-mode-only\" /\u003e\n\u003cimg alt=\"banner\" src=\"https://raw.githubusercontent.com/BearToCode/mismerge/master/images/banner-dark.png#gh-dark-mode-only\" /\u003e\n\n## A web-based merge editor\n\nMismerge is a modern two-way and one-way merge editor for the web, built with **Svelte**. You can [visit the demo](https://beartocode.github.io/mismerge/) and start merging now, or use it as a component for your project. It is also available in **React** and **Vue**.\n\n## Features\n\n- ▶️ One way merge editor\n- 🔀 Two way merge editor\n- 📑 Support lines wrapping\n- 🌈 Support syntax highlighting\n- ➖ Can ignore whitespace\n- 📜 Custom input history\n- 🔠 Can ignore case\n- 🔢 Blocks, words and chars counter\n- ✅ Works in SvelteKit \u0026 TypeScript\n- 🌎 Available in React \u0026 Vue\n\n## Installation\n\n```\nnpm i @mismerge/core\n```\n\n## Usage\n\n### Svelte\n\n```svelte\n\u003cscript\u003e\n\timport { MisMerge3 } from '@mismerge/core';\n\t// Core styles, required for the editor to work properly\n\timport '@mismerge/core/styles.css';\n\n\timport '@mismerge/core/light.css';\n\t// Or  '@mismerge/core/dark.css';\n\n\tlet lhs = 'foo';\n\tlet ctr = 'bar';\n\tlet rhs = 'baz';\n\u003c/script\u003e\n\n\u003c!-- Left-hand side and right-hand side constant text --\u003e\n\u003cMisMerge3 {lhs} {rhs} bind:ctr /\u003e\n\n\u003c!-- All sides editable --\u003e\n\u003cMisMerge3 bind:lhs bind:ctr bind:rhs lhsEditable rhsEditable \u003e\n\n\u003cstyle\u003e\n  :global(.mismerge) {\n    font-family: monospace;\n    min-height: 600px;\n  }\n\u003c/style\u003e\n```\n\n### React\n\nInstall the **additional** adapter package:\n\n```\nnpm i @mismerge/react\n```\n\n```jsx\nimport { DefaultDarkColors, MisMerge3 } from '@mismerge/react';\nimport { useEffect, useState } from 'react';\nimport '@mismerge/core/styles.css';\nimport '@mismerge/core/dark.css';\n\nfunction App() {\n\tconst [ctr, setCtr] = useState('Hello world!');\n\n\tuseEffect(() =\u003e {\n\t\tconsole.log(ctr);\n\t}, [ctr]);\n\n\treturn (\n\t\t\u003c\u003e\n\t\t\t\u003cMisMerge3\n\t\t\t\tlhs=\"Hello world!\"\n\t\t\t\tctr={ctr}\n\t\t\t\trhs=\"Hello world!\"\n\t\t\t\tonCtrChange={setCtr}\n\t\t\t\tcolors={DefaultDarkColors}\n\t\t\t\twrapLines={true}\n\t\t\t/\u003e\n\t\t\u003c/\u003e\n\t);\n}\n```\n\n### Vue\n\nInstall the **additional** adapter package:\n\n```\nnpm i @mismerge/vue\n```\n\n\u003e [!NOTE]  \n\u003e Due to some differences in how Vue treats boolean attributes, some default properties may not correspond to the ones described in the API section.\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\nimport { MisMerge3, DefaultDarkColors } from '@mismerge/vue';\nimport '@mismerge/core/styles.css';\nimport '@mismerge/core/dark.css';\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n\t\u003cMisMerge3\n\t\tlhs=\"Hello\"\n\t\tctr=\"World\"\n\t\trhs=\"!\"\n\t\tctr-editable\n\t\t:colors=\"DefaultDarkColors\"\n\t\t:on-ctr-change=\"console.log\"\n\t/\u003e\n\u003c/template\u003e\n```\n\n## Customization\n\n### Adding syntax highlighting\n\nYou need to provide your own syntax highlighter. Example and demo using [Shiki-JS](https://github.com/shikijs/shiki). The highlighter can be either sync or async.\n\n```svelte\n\u003cscript\u003e\n\timport { codeToHtml } from 'shiki';\n\t// ...\n\n\tconst highlight = async (text: string) =\u003e\n\t\tawait codeToHtml(text, {\n\t\t\tlang: 'js',\n\t\t\ttheme: 'min-dark'\n\t\t});\n\u003c/script\u003e\n\n\u003cMisMerge3 ... {highlight} /\u003e\n```\n\n### Changing connections colors\n\n```svelte\n\u003cscript\u003e\n\timport { DefaultDarkColors } from '@mismerge/core';\n\t// ...\n\u003c/script\u003e\n\n\u003cMisMerge3 ... colors={DefaultDarkColors} /\u003e\n```\n\n### Styles\n\nIf you want to customize the editor styles, you can copy the default [light](https://github.com/BearToCode/mismerge/blob/master/packages/core/src/lib/styles/light.css) or [dark](https://github.com/BearToCode/mismerge/blob/master/packages/core/src/lib/styles/dark.css) theme and adapt it to your need.\n\nHere is a basic explanation of how the the rendered html looks like:\n\n```html\n\u003cdiv class=\"mismerge\"\u003e\n\t\u003cdiv\u003e\n\t\t\u003c!-- Main --\u003e\n\t\t\u003cdiv class=\"msm__main\"\u003e\n\t\t\t\u003c!-- View --\u003e\n\t\t\t\u003cdiv class=\"msm__view\"\u003e\n\t\t\t\t\u003c!-- Content --\u003e\n\t\t\t\t\u003cdiv class=\"msm__view-content\"\u003e\n\t\t\t\t\t\u003c!-- Blocks wrapper --\u003e\n\t\t\t\t\t\u003cdiv class=\"msm__wrapper\"\u003e\n\t\t\t\t\t\t\u003c!-- Blocks --\u003e\n\t\t\t\t\t\t\u003cdiv data-component-id=\"abcdefgh\" class=\"msm__block block-type\"\u003e\n\t\t\t\t\t\t\t\u003c!-- Lines --\u003e\n\t\t\t\t\t\t\t\u003cdiv class=\"msm__line\"\u003e\n\t\t\t\t\t\t\t\t\u003c!-- ... --\u003e\n\t\t\t\t\t\t\t\u003c/div\u003e\n\t\t\t\t\t\t\t\u003c!-- ... --\u003e\n\t\t\t\t\t\t\u003c/div\u003e\n\t\t\t\t\t\t\u003c!-- ... --\u003e\n\t\t\t\t\t\u003c/div\u003e\n\n\t\t\t\t\t\u003c!-- Highlight overlay --\u003e\n\t\t\t\t\t\u003cdiv class=\"msm__highlight-overlay\"\u003e\n\t\t\t\t\t\t\u003c!-- ... --\u003e\n\t\t\t\t\t\u003c/div\u003e\n\n\t\t\t\t\t\u003c!-- Input --\u003e\n\t\t\t\t\t\u003ctextarea /\u003e\n\t\t\t\t\u003c/div\u003e\n\n\t\t\t\t\u003c!-- Side panel --\u003e\n\t\t\t\t\u003cdiv class=\"msm__side-panel\"\u003e\n\t\t\t\t\t\u003c!-- ... --\u003e\n\t\t\t\t\u003c/div\u003e\n\t\t\t\u003c/div\u003e\n\t\t\u003c/div\u003e\n\t\u003c/div\u003e\n\n\t\u003c!-- Footer --\u003e\n\t\u003cdiv class=\"msm__footer\"\u003e\n\t\t\u003c!-- ... --\u003e\n\t\u003c/div\u003e\n\u003c/div\u003e\n```\n\n## API\n\nA list of properties for `\u003cMisMerge2\u003e`(2), `\u003cMisMerge3\u003e`(3), or both.\n\n| Property                | Type                                            | Default               | Description                                       | Component |\n| ----------------------- | ----------------------------------------------- | --------------------- | ------------------------------------------------- | --------- |\n| `lhs`                   | `string`                                        | `\"\"`                  | Left-hand side text                               | Both      |\n| `ctr`                   | `string`                                        | `\"\"`                  | Center text                                       | 3         |\n| `rhs`                   | `string`                                        | `\"\"`                  | Right-hand side text                              | Both      |\n| `colors`                | `EditorColors`                                  | `DefaultLightColors`  | Connections colors                                | Both      |\n| `highlight`             | `(text: string) =\u003e string \\| Promise\u003cstring\u003e`   | `undefined`           | Syntax highlighter                                | Both      |\n| `lhsEditable`           | `boolean`                                       | `true`(2), `false`(3) | Can edit left panel                               | Both      |\n| `ctrEditable`           | `boolean`                                       | `true`                | Can edit center panel                             | 3         |\n| `rhsEditable`           | `boolean`                                       | `true`(2), `false`(3) | Can edit right panel                              | Both      |\n| `lineDiffAlgorithm`     | `'characters' \\| 'words' \\| 'words_with_space'` | `words_with_space`    | Diff algorithm for same line side by side diff    | Both      |\n| `disableMerging`        | `boolean`                                       | `false`               | Disables merging                                  | Both      |\n| `wrapLines`             | `boolean`                                       | `false`               | Enables lines wrapping                            | Both      |\n| `disableWordsCounter`   | `boolean`                                       | `false`               | Disables words counter                            | Both      |\n| `disableCharsCounter`   | `boolean`                                       | `false`               | Disables chars counter                            | Both      |\n| `disableBlocksCounters` | `boolean`                                       | `false`               | Disables blocks counter                           | Both      |\n| `disableFooter`         | `boolean`                                       | `false`               | Disables footer                                   | Both      |\n| `ignoreWhitespace`      | `boolean`                                       | `false`               | Ignore whitespace in diff                         | Both      |\n| `ignoreCase`            | `boolean`                                       | `false`               | Ignore case in diff                               | Both      |\n| `conflictsResolved`     | `boolean`                                       | -                     | Binding for when all conflicts have been resolved | 3         |\n\nEvents (available for Svelte):\n\n| Name          | Description                                                   |\n| ------------- | ------------------------------------------------------------- |\n| `on:merge`    | Fired when a block is merged from one side to an adjacent one |\n| `on:resolve`  | Fired when a conflict has its resolved status toggled         |\n| `on:delete`   | Fired when a block is deleted in the center side              |\n| `on:input`    | Default `textarea` event                                      |\n| `on:keydown`  | Default `textarea` event                                      |\n| `on:keypress` | Default `textarea` event                                      |\n| `on:keyup`    | Default `textarea` event                                      |\n\n## Contributing\n\n### Project setup\n\nClone the repo:\n\n```\ngit clone https://github.com/BearToCode/mismerge.git\ncd mismerge\n```\n\nDownload dependencies for all packages in the monorepo:\n\n```\nnpm install\n```\n\n### The core package\n\nThe core package is inside `packages/core`. You can run the associated sveltekit app using `npm run core` or `cd packages/core` \u0026 `npm run dev`.\n\n### The demo\n\nThe demo is inside the `demo` root folder. You can run it from root using `npm run demo` or `cd demo` \u0026 `npm run dev`.\nIt is automatically deployed to Github Pages with every push to master.\n\n### Committing\n\nThis repository uses [commitizen](https://github.com/commitizen/cz-cli) to enforce similar commit messages. Commit using:\n\n```\nnpm run commit\n# or\ngit cz\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBearToCode%2Fmismerge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBearToCode%2Fmismerge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBearToCode%2Fmismerge/lists"}