{"id":19807613,"url":"https://github.com/notninja/nevis","last_synced_at":"2026-01-24T18:03:12.271Z","repository":{"id":57153328,"uuid":"68757657","full_name":"NotNinja/nevis","owner":"NotNinja","description":"Makes JavaScript more object-orientated","archived":false,"fork":false,"pushed_at":"2024-04-17T08:22:03.000Z","size":263,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-13T20:51:55.007Z","etag":null,"topics":["browser","equals","hashcode","inheritance","javascript","nodejs","oop"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/NotNinja.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-20T22:13:24.000Z","updated_at":"2021-08-28T00:33:39.000Z","dependencies_parsed_at":"2024-11-12T13:01:03.862Z","dependency_job_id":null,"html_url":"https://github.com/NotNinja/nevis","commit_stats":{"total_commits":57,"total_committers":1,"mean_commits":57.0,"dds":0.0,"last_synced_commit":"1885e154e6e52d8d3eb307da9f27ed591bac455c"},"previous_names":["skelp/oopsy"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Fnevis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Fnevis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Fnevis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Fnevis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NotNinja","download_url":"https://codeload.github.com/NotNinja/nevis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251840257,"owners_count":21652309,"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":["browser","equals","hashcode","inheritance","javascript","nodejs","oop"],"created_at":"2024-11-12T09:11:26.835Z","updated_at":"2026-01-24T18:03:12.224Z","avatar_url":"https://github.com/NotNinja.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"    888b    888                   d8b\n    8888b   888                   Y8P\n    88888b  888\n    888Y88b 888  .d88b.  888  888 888 .d8888b\n    888 Y88b888 d8P  Y8b 888  888 888 88K\n    888  Y88888 88888888 Y88  88P 888 \"Y8888b.\n    888   Y8888 Y8b.      Y8bd8P  888      X88\n    888    Y888  \"Y8888    Y88P   888  88888P'\n\n[Nevis](https://github.com/NotNinja/nevis) brings more of the Object-Orientated Programming (OOP) model to JavaScript.\n\n[![Build Status](https://img.shields.io/travis/NotNinja/nevis/develop.svg?style=flat-square)](https://travis-ci.org/NotNinja/nevis)\n[![Coverage](https://img.shields.io/codecov/c/github/NotNinja/nevis/develop.svg?style=flat-square)](https://codecov.io/gh/NotNinja/nevis)\n[![Dev Dependency Status](https://img.shields.io/david/dev/NotNinja/nevis.svg?style=flat-square)](https://david-dm.org/NotNinja/nevis?type=dev)\n[![License](https://img.shields.io/npm/l/nevis.svg?style=flat-square)](https://github.com/NotNinja/nevis/blob/master/LICENSE.md)\n[![Release](https://img.shields.io/npm/v/nevis.svg?style=flat-square)](https://www.npmjs.com/package/nevis)\n\n* [Install](#install)\n* [API](#api)\n* [Why Nevis?](#why-nevis)\n* [Migrating from Oopsy](#migrating-from-oopsy)\n* [Bugs](#bugs)\n* [Contributors](#contributors)\n* [License](#license)\n\n## Install\n\nInstall using the package manager for your desired environment(s):\n\n``` bash\n$ npm install --save nevis\n# OR:\n$ bower install --save nevis\n```\n\nYou'll need to have at least [Node.js](https://nodejs.org) and you'll only need [Bower](https://bower.io) if you want to\ninstall that way instead of using `npm`. While equals should be compatible with all versions of\n[Node.js](https://nodejs.org), it is only tested against version 4 and above.\n\nIf you want to simply download the file to be used in the browser you can find them below:\n\n* [Development Version](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis.js) (81kb - [Source Map](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis.js.map))\n* [Production Version](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis.min.js) (9.2kb - [Source Map](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis.min.js.map))\n\nIf you're only wanting support for inheritance, you can use the *lite* version instead:\n\n* [Development Version - Lite](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis-lite.js) (7.5kb - [Source Map](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis-lite.js.map))\n* [Production Version - Lite](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis-lite.min.js) (981b - [Source Map](https://cdn.rawgit.com/NotNinja/nevis/master/dist/nevis-lite.min.js.map))\n\n## API\n\n### Inheritance\n\nNevis' primary function is to provide clean implementation of single inheritance.\n\n\u003e Available in *lite* version\n\n``` javascript\nNevis.extend([name][, constructor][, prototype][, statics])\n```\n\nExtends the constructor to which this method is associated with the `prototype` and/or `statics` provided.\n\nIf `name` is provided, it will be used as the class name and can be accessed via a special `class_` property on the\nchild constructor, otherwise the class name of the super constructor will be used instead. The class name may also be\nused string representation for instances of the child constructor (via `toString`), but this is not applicable to the\n*lite* version of Nevis.\n\nIf `constructor` is provided, it will be used as the constructor for the child, otherwise a simple constructor which\nonly calls the super constructor will be used instead.\n\nThe super constructor can be accessed via a special `super_` property on the child constructor.\n\nIt is very flexible and can be used to extend *classes*:\n\n``` javascript\nvar Base = Nevis.extend('Base', function(attributes) {\n  this.attributes = attributes || {};\n}, {\n  getAttribute: function(name) {\n    return this.attributes[name];\n  },\n  setAttribute: function(name, value) {\n    this.attributes[name] = value;\n  }\n});\n\nvar Person = Base.extend('Person', function(name, attributes) {\n  Person.super_.call(this, attributes);\n\n  this.name = name;\n\n  Person.people.push(this);\n}, {\n  greet: function(name) {\n    return 'Hello ' + name + ', my name is ' + this.name;\n  }\n}, {\n  people: []\n});\n\nvar bob = new Person('Bob', { age: 58 });\n\nbob.name;\n//=\u003e \"Bob\"\nbob.greet('Suzie');\n//=\u003e \"Hello Suzie, my name is Bob\"\nbob.getAttribute('age');\n//=\u003e 58\nPerson.people;\n//=\u003e [ \"Bob\" ]\n```\n\nAlso, this can be used to extend external classes such as `EventEmitter`:\n\n``` javascript\nvar EventEmitter = require('events').EventEmitter;\nvar Nevis = require('nevis');\n\nvar Events = Nevis.extend('Events', function() {\n  EventEmitter.call(this);\n}, EventEmitter.prototype, EventEmitter);\n```\n\nHowever, this last approach has the caveats of `instanceof` not identifying this kind of inheritance and `super_` will\nonly reference the constructor that is extended.\n\n### Equality\n\nNevis adds a means of testing whether an object is equal to another that's more advanced than just `==` or `===`.\n\n\u003e Unavailable in *lite* version\n\n``` javascript\nNevis.prototype.equals(obj)\n```\n\nReturns whether the instance is \"equal to\" the specified `obj`.\n\nThis method implements an equivalence relation on non-null object references:\n\n* It is *reflexive*: for any non-null reference value `x`, `x.equals(x)` should return `true`.\n* It is *symmetric*: for any non-null reference values `x` and `y`, `x.equals(y)` should return `true` if and only if\n  `y.equals(x)` returns `true`.\n* It is *transitive*: for any non-null reference values `x`, `y`, and `z`, if `x.equals(y)` returns `true` and\n  `y.equals(z)` returns `true`, then `x.equals(z)` should return `true`.\n* It is *consistent*: for any non-null reference values `x` and `y`, multiple invocations of `x.equals(y)` consistently\n  return `true` or consistently return `false`, provided no information used in `equals` comparisons on the objects is\n  modified.\n* For any non-null reference value `x`, `x.equals(null)` should return `false`.\n\nThe default implementation of this method is the most discriminating possible equivalence relation on objects; that is,\nfor any non-null reference values `x` and `y`, this method returns `true` if, and only if, `x` and `y` are exactly equal\n(`x === y` has the value `true`).\n\nPlease note that it is generally necessary to override the `Nevis.prototype.hashCode` method whenever this method is\noverridden, so as to maintain the general contract for the `Nevis.prototype.hashCode` method, which states that equal\nobjects must have equal hash codes.\n\n``` javascript\nvar Person = Nevis.extend('Person', function(name, age) {\n  this.name = name;\n  this.age = age;\n}, {\n  greet: function(name) {\n    return 'Hello ' + name + ', my name is ' + this.name;\n  }\n});\nvar bob = new Person('Bob', 58);\nvar suzie = new Person('Suzie', 30);\n\nbob.equals(bob);\n//=\u003e true\nbob.equals(new Person('Bob', 58));\n//=\u003e false\nbob.equals(suzie);\n//=\u003e false\nbob.equals(null);\n//=\u003e false\nbob.equals(undefined);\n//=\u003e false\n```\n\nContinue reading for information on how to create a good equals for complex classes using `Nevis.EqualsBuilder`.\n\n---\n\nNevis also provides a null-safe static method for testing the equality of two values of any type.\n\n``` javascript\nNevis.equals(value, other[, options])\n```\n\nReturns whether the specified `value` is \"equal to\" the `other` provided using the given `options`.\n\nConsequently, if both arguments are `null`, `true` is returned and if exactly one argument is `null`, `false` is\nreturned. Otherwise, this method implements an equivalence relation on non-null object references in the same way as\n`Nevis.prototype.equals`.\n\nIf neither value is `null` and both are not exactly (strictly) equal, this method will first check whether `value` has a\nmethod named \"equals\" and, if so, return the result of calling that method with `other` passed to it. If no \"equals\"\nmethod exists on `value` or if the `ignoreEquals` option is enabled, it will attempt to test the equality internally\nbased on their type.\n\nPlain objects are tested recursively for their properties and collections (e.g. arrays) are also tested recursively for\ntheir elements.\n\nThe `options` parameter is entirely optional and supports the following:\n\n| Option            | Type     | Default | Description                                                                                                                                                           |\n| ----------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `filterProperty`  | Function | N/A     | A function to be called to filter properties for objects to determine whether they should be tested. Not called for method properties when `ignoreMethods` is `true`. |\n| `ignoreCase`      | Boolean  | `false` | Whether to ignore case when testing equality for strings.                                                                                                             |\n| `ignoreEquals`    | Boolean  | `false` | Whether to ignore the `equals` method on `value`, when present                                                                                                        |\n| `ignoreInherited` | Boolean  | `false` | Whether to ignore inherited properties when testing equality for objects.                                                                                             |\n| `ignoreMethods`   | Boolean  | `false` | Whether to ignore method properties when testing equality for objects.                                                                                                |\n\n``` javascript\nvar obj = {\n  foo: 'bar',\n  doSomething: function() {\n    return 123;\n  }\n};\n\nNevis.equals(obj, obj);\n//=\u003e true\nNevis.equals(obj, {\n  foo: 'bar',\n  doSomething: function() {\n    return 321;\n  }\n});\n//=\u003e false\nNevis.equals(obj, {\n  foo: 'bar',\n  doSomething: function() {\n    return 321;\n  }\n}, { ignoreMethods: true });\n//=\u003e true\nNevis.equals(bob, bob);\n//=\u003e true\nNevis.equals(bob, new Person('Bob', 58));\n//=\u003e false\nNevis.equals(bob, suzie);\n//=\u003e false\nNevis.equals('foo', 'foo');\n//=\u003e true\nNevis.equals('foo', 'FOO');\n//=\u003e false\nNevis.equals('foo', 'FOO', { ignoreCase: true });\n//=\u003e true\nNevis.equals(NaN, NaN);\n//=\u003e true\nNevis.equals(null, null);\n//=\u003e true\nNevis.equals(undefined, undefined);\n//=\u003e true\nNevis.equals(null, undefined);\n//=\u003e false\nNevis.equals(bob, null);\n//=\u003e false\nNevis.equals(bob, undefined);\n//=\u003e false\n```\n\n---\n\nNevis provides a builder to support creating good equals for complex classes.\n\n\u003e Unavailable in *lite* version\n\n``` javascript\nNevis.EqualsBuilder()\n```\n\nThe best way to describe it is by using an example that demonstrates it's API:\n\n``` javascript\nvar Animal = Nevis.extend('Animal', function(species) {\n  this.species = species;\n}, {\n  equals: function(obj) {\n    if (obj == null) {\n      return false;\n    }\n\n    return new Nevis.EqualsBuilder()\n      .append(this.species, obj.species)\n      .build();\n  }\n});\nvar Human = Nevis.extend('Human', function(name, age) {\n  Human.super_.call(this, 'human');\n\n  this.name = name;\n  this.age = age;\n}, {\n  equals: function(obj) {\n    if (obj == null) {\n      return false;\n    }\n\n    return new Nevis.EqualsBuilder()\n      .appendSuper(Human.super_.prototype.equals.call(this, obj))\n      .append(this.name, obj.name)\n      .append(this.age, obj.age)\n      .build();\n  }\n});\nvar Lion = Nevis.extend('Lion', function(name, age) {\n  Lion.super_.call(this, 'lion');\n\n  this.name = name;\n  this.age = age;\n}, {\n  equals: function(obj) {\n    if (obj == null) {\n      return false;\n    }\n\n    return new Nevis.EqualsBuilder()\n      .appendSuper(Lion.super_.prototype.equals.call(this, obj))\n      .append(this.name, obj.name)\n      .append(this.age, obj.age)\n      .build();\n  }\n});\nvar humanBob = new Human('Bob', 58);\nvar humanSuzie = new Human('Suzie', 30);\nvar lionBob = new Lion('Bob', 58);\n\nhumanBob.equals(humanBob);\n//=\u003e true\nhumanBob.equals(new Human('Bob', 58));\n//=\u003e true\nhumanBob.equals(lionBob);\n//=\u003e false\nhumanBob.equals(humanSuzie);\n//=\u003e false\nhumanSuzie.name = 'Bob';\nhumanSuzie.age = 58;\nhumanBob.equals(humanSuzie);\n//=\u003e true\nhumanBob.equals(null);\n//=\u003e false\nhumanBob.equals(undefined);\n//=\u003e false\n```\n\nWhen using `Nevis.EqualsBuilder` in an `equals` method, it's recommended to use `Nevis.HashCodeBuilder` in the\n`hashCode` method on the same object.\n\n### Hash Codes\n\nNevis introduces JavaScript to the Java concept of hash codes.\n\n\u003e Unavailable in *lite* version\n\n``` javascript\nNevis.prototype.hashCode()\n```\n\nReturns the hash code for the instance. This method is supported for the benefit of hash tables.\n\nThe general contract of `hashCode` is:\n\n* Whenever it is invoked on the same instance more than once during an execution of an application, the `hashCode`\n  method must consistently return the same number, provided no information used to generate the hash code on the\n  instance is modified. This number need not remain consistent from one execution of an application to another execution\n  of the same application.\n* If two instances are equal, that calling the `hashCode` method on each of the two instances must produce the same\n  number result.\n* It is not required that if two instances are unequal, that calling the `hashCode` method on each of the two instances\n  must produce distinct number results. However, the programmer should be aware that producing distinct number results\n  for unequal instances may improve the performance of hash tables.\n\nThe default implementation of this method will attempt to generate the hash code based on all of the fields on the\ninstance. Please note that it is generally necessary to override the `Nevis.prototype.equals` method whenever this\nmethod is overridden, so as to maintain the above contract where equal objects must have equal hash codes.\n\n``` javascript\nvar Person = Nevis.extend('Person', function(name) {\n  this.name = name;\n}, {\n  greet: function(name) {\n    return 'Hello ' + name + ', my name is ' + this.name;\n  }\n});\nvar bob = new Person('Bob');\nvar suzie = new Person('Suzie');\n\nbob.hashCode();\n//=\u003e -469006311\nsuzie.hashCode();\n//=\u003e -388699942\nbob.hashCode() === new Person('Bob').hashCode();\n//=\u003e true\n```\n\nContinue reading for information on how to generate hash codes for complex classes using `Nevis.HashCodeBuilder`.\n\n---\n\nNevis also provides a null-safe static method for generating a hash code for any value.\n\n``` javascript\nNevis.hashCode(value[, options])\n```\n\nReturns a hash code for the specified `value` using the `options` provided. This method is supported for the benefit of\nhash tables and it has the same general contract as `Nevis.prototype.hashCode`.\n\nIf `value` is `null`, this method will always return zero. Otherwise, it will check whether `value` has a method named\n\"hashCode\" and, if so, return the result of calling that method. If no \"hashCode\" method exists on `value` or if the\n`ignoreHashCode` option is enabled, it will attempt to generate the hash code internally based on its type.\n\nPlain objects are hashed recursively for their properties and collections (e.g. arrays) are also hashed recursively for\ntheir elements.\n\nThe `options` parameter is entirely optional and supports the following:\n\n| Option            | Type     | Default | Description                                                                                                                                                             |\n| ----------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `allowCache`      | Boolean  | `true`  | Whether to allow hash codes generated for certain immutable types to be cached for faster re-generation.                                                                |\n| `filterProperty`  | Function | N/A     | A function to be called to filter properties for objects to determine whether they should be included. Not called for method properties when `ignoreMethods` is `true`. |\n| `ignoreHashCode`  | Boolean  | `false` | Whether to ignore the `hashCode` method on `value`, when present                                                                                                        |\n| `ignoreInherited` | Boolean  | `false` | Whether to ignore inherited properties when generating hash codes for objects.                                                                                          |\n| `ignoreMethods`   | Boolean  | `false` | Whether to ignore method properties when generating hash codes for objects.                                                                                             |\n\n``` javascript\nvar obj = {\n  foo: 'bar',\n  doSomething: function() {\n    return 123;\n  }\n};\n\nNevis.hashCode(obj);\n//=\u003e 1343675198\nNevis.hashCode(obj, { ignoreMethods: true });\n//=\u003e 61653\nNevis.hashCode(bob);\n//=\u003e -469006311\nNevis.hashCode('foo');\n//=\u003e 101574\nNevis.hashCode(null);\n//=\u003e 0\nNevis.hashCode(undefined);\n//=\u003e 0\n```\n\n---\n\nNevis provides a builder to support generating hash codes for complex classes.\n\n\u003e Unavailable in *lite* version\n\n``` javascript\nNevis.HashCodeBuilder([initial][, multipler])\n```\n\nIdeally the `initial` value and `multiplier` should be different for each class, however, this is not vital. Prime\nnumbers are preferred, especially for `multiplier`.\n\nIf specified, both `initial` and `multiplier` *must* be odd numbers.\n\nThe best way to describe it is by using an example that demonstrates it's API:\n\n``` javascript\nvar Animal = Nevis.extend('Animal', function(species) {\n  this.species = species;\n}, {\n  hashCode: function() {\n    return new Nevis.HashCodeBuilder()\n      .append(this.species)\n      .build();\n  }\n});\nvar Human = Nevis.extend('Human', function(name, age) {\n  Human.super_.call(this, 'human');\n\n  this.name = name;\n  this.age = age;\n}, {\n  hashCode: function() {\n    return new Nevis.HashCodeBuilder()\n      .appendSuper(Human.super_.prototype.hashCode.call(this))\n      .append(this.name)\n      .append(this.age)\n      .build();\n  }\n});\nvar Lion = Nevis.extend('Lion', function(name, age) {\n  Lion.super_.call(this, 'lion');\n\n  this.name = name;\n  this.age = age;\n}, {\n  hashCode: function() {\n    return new Nevis.HashCodeBuilder()\n      .appendSuper(Lion.super_.prototype.hashCode.call(this))\n      .append(this.name)\n      .append(this.age)\n      .build();\n  }\n});\nvar humanBob = new Human('Bob', 58);\nvar humanSuzie = new Human('Suzie', 30);\nvar lionBob = new Lion('Bob', 58);\n\nhumanBob.hashCode();\n//=\u003e 1795252862788\nhumanBob.hashCode() === new Human('Bob', 58).hashCode();\n//=\u003e true\nlionBob.hashCode();\n//=\u003e -79783715387\nhumanSuzie.hashCode();\n//=\u003e 1908159460360\nhumanSuzie.name = 'Bob';\nhumanSuzie.age = 58;\nhumanBob.hashCode() === humanSuzie.hashCode();\n//=\u003e true\n```\n\nWhen using `Nevis.HashCodeBuilder` in a `hashCode` method, it's recommended to use `Nevis.EqualsBuilder` in the `equals`\nmethod on the same object.\n\n### String Representations\n\nNevis builds on top of JavaScript's `toString` method to make it easier to use.\n\n\u003e Unavailable in *lite* version\n\n``` javascript\nNevis.prototype.toString()\n```\n\nReturns a string representation of the instance.\n\nIn general, this method returns a string that \"textually represents\" the instance. The result should be a concise but\ninformative representation that is easy for a person to read.\n\nThe default implementation of this method will return a string consisting of the instance's class name, the at-sign\ncharacter (`@`), and the hexadecimal representation of the hash code of the instance.\n\n``` javascript\nvar RandomHolder = Nevis.extend('RandomHolder', function() {\n  this.value = Math.random() * 100;\n})\nvar random = new RandomHolder();\n\nrandom.toString();\n//=\u003e \"RandomHolder@f9fa743\"\n\nvar UnnamedObject = Nevis.extend({\n  foo: 'bar',\n  fu: 'baz'\n});\nvar unnamed = new UnnamedObject();\n\nunnamed.toString();\n//=\u003e \"Nevis@-3fff8d24\"\n```\n\n---\n\nNevis also provides a null-safe static method for getting string representations of any value.\n\n``` javascript\nNevis.toString(value)\n```\n\nReturns the result of calling the `toString` method on the specified `value` when it is non-null.\n\nIf value is `null` or `undefined`, this method will return `\"null\"` or `\"undefined\"` respectively.\n\n``` javascript\nNevis.toString(random);\n//=\u003e \"RandomHolder@f9fa743\"\nNevis.toString(123);\n//=\u003e \"123\"\nNevis.toString(null);\n//=\u003e \"null\"\nNevis.toString(undefined);\n//=\u003e \"undefined\"\n```\n\n## Why Nevis?\n\nBecause we love Scotland and it is named after [Ben Nevis](https://en.wikipedia.org/wiki/Ben_Nevis) since we felt like\nwe conquered a mountain when creating this library.\n\n## Migrating from Oopsy\n\nIf you've been using Oopsy (the former name for Nevis), then you should find migrating to Nevis really easy. All you\nreally need to do is find and replace \"Oopsy\" with \"Nevis\" and you'll have all of the old functionality and more.\n\nIf you don't want all of the additional functionality and only care about inheritance, you can use the *lite* version of\nNevis.\n\n## Bugs\n\nIf you have any problems with Nevis or would like to see changes currently in development you can do so\n[here](https://github.com/NotNinja/nevis/issues).\n\n## Contributors\n\nIf you want to contribute, you're a legend! Information on how you can do so can be found in\n[CONTRIBUTING.md](https://github.com/NotNinja/nevis/blob/master/CONTRIBUTING.md). We want your suggestions and pull\nrequests!\n\nA list of Nevis contributors can be found in [AUTHORS.md](https://github.com/NotNinja/nevis/blob/master/AUTHORS.md).\n\n## License\n\nSee [LICENSE.md](https://github.com/NotNinja/nevis/raw/master/LICENSE.md) for more information on our MIT license.\n\n[![Copyright !ninja](https://cdn.rawgit.com/NotNinja/branding/master/assets/copyright/base/not-ninja-copyright-186x25.png)](https://not.ninja)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotninja%2Fnevis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotninja%2Fnevis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotninja%2Fnevis/lists"}