So you want to start work on I2P? Great! Here's a quick guide to getting started on contributing to the website or the software, doing development or creating translations.

Not quite ready for coding? Try getting involved first.

Basic study

Basic development on the I2P router or the embedded applications uses Java as the main development language. If you don't have experience with Java, you can always have a look at Thinking in Java.

Study the how intro, the other "how" documents, the tech intro, and associated documents. These will give you a good overview of how I2P is structured and what different things it does.

Getting the I2P code

For development on the I2P router or the embedded applications, there are two ways to get the source code:

The easy way: Git


The Git repository is currently a read-only mirror. If you wish to use it for development, you will need to submit patches to our issue tracker. We can accept GitHub pull requests, but they must be processed manually by turning them into patches anyway.

The proper way: Monotone

  • Install monotone. Monotone is a version control system. We use it because it allows us to keep track of who does what changes to the source code (and for a lot of complicated things, but 'keeping track of changes' is the basic idea).
  • Skim over the monotone tutorial, to make sure you understand the concepts.
  • If you want to remain anonymous, you need to do an additional step, to set up a connection to a monotone server over I2P:

    Enable the i2ptunnel client tunnel on port 8998 pointing to mtn.i2p-projekt.i2p.

  • Pick a directory where you want to put all your I2P files, and create a monotone database: mtn -d db init
  • Define the trust list by creating ~/.monotone/monotonerc (or _MTN/monotonerc in the i2p.i2p workspace) with the following contents:
    -- This implements a list of trusted signers.
    -- It is used on checkout and update.
    -- It is not used for repo sync/push/pull.
    -- If you do not include this function in ~/.monotone/monotonerc, the
    -- default is to trust everybody, which is probably a bad thing
    -- in an anonymous network.
    -- Update the list below to reflect the signers YOU trust.
    -- ref:
    -- Modified to use key identities instead of key names, since
    -- monotone allows duplicate key names, so any key-name-based
    -- trust system is insecure.
    --  Modified from intersection() to use key identities instead of key names, since
    --  monotone allows duplicate key names.
    --  a: table of ID structures (see above)
    --  b: table of hex IDs
    function keyintersection(a,b)
        local s={}
        local t={}
        for k,v in pairs(a) do s[] = 1 end
        for k,v in pairs(b) do if s[v] ~= nil then table.insert(t,v) end end
        return t
    -- from mtn source project.hh and
    -- signers is a table of integers (starting with 1) to the following ID structure:
    -- struct ID
    -- {
    --   id: (key_id in key_identity_info) hex of revision id hash;
    --   given_name: (given_name in key_identity_info) // name given when creating the key
    --   name: (official_name in key_identity_info) // name returned by hooks or (once implented) policy
    -- };
    -- id: hex of revision id hash;
    -- name: cert_name
    -- val: cert_value
    function get_revision_cert_trust(signers, id, name, val)
       local trusted_signers = {
    		"5bc185cfd680eb512fdb9626b9fb4298e136215e",	--  BlubMail@mail.i2p
    		"f6706ac205e6b5d7a7e3ea4244ab0ef497f0a099",	--  cervantes@mail.i2p
    		"690f278ff6c6157cbaf23b0d602b6d6dcf368313",	--  complication@mail.i2p
    		"eb4ac08d5ddbb2bd73889f86c1211424025a6f07",	--
    		"aae785027c240ebbb0a883fd8ebcf8d6ecee4104",	--
    		"86478595288d1b96b58f0c8cd8a8971bc430f8fd",	--  dg2@mail.i2p
    		-- completed dev agreement 2013-07 but never checked in anything
    		--"5f75b8f0769770edc3267c21ddc9a00ddae31394",	--  digit@mail.i2p
    		"4ebaace9973913416af92ee8d0fb93d64753df4c",	--  dream@mail.i2p
    		"7e498ae94c9c322404adfc61b16bed388095906b",	--  duck@mail.i2p
    		"6c728b0ffed3c2bf7fb0f3c583b30f966d9bacd5",	--  echelon2@mail.i2p
    		"0e4e7ebebafbdf4cdacc45a47ba155b1215d8e8b",	--  forget@mail.i2p
    		"f332b3d3b11b2efdae220cea75b9d5ba9ec3b52d",	--  hamada@mail.i2p
    		"e246444b4fe69ba599e13403c4ab931066de902f",	--  hiddenz@mail.i2p
    		"a61146ee69ddb9fcf3b82b19a62b8114b60d367e",	--  HungryHobo@mail.i2p
    		"4844b1fd45f5a68744fa28d2f3e3b61a3cf83b95",	--  kytv@mail.i2p
    		"c9b970f5e8917eada663d4c6b22096617021c95c",	--  m1xxy@mail.i2p
    		"3be64909d6ab7c3d7afe16f20f24e672708b576b",	--  magma@mail.i2p
    		"2977a6f4e11819a3f928783175caadc0071fc4de",	--  mathiasdm@mail.i2p
    		"de9d196e8057e1629178edbfa1ed754c648d7340",	--  meeh@mail.i2p
    		"2a0bba98558d7a9d7e4b1bd807789601252c0024",	--  mkvore-commit@mail.i2p
    		"6ade4b7a9a6425194f482ab351950e4230dbbc85",	--  neutron@mail.i2p
    		"bc74b49fd8a20513b2745a3d13414b7e9818dd18",	--  Oldaris@mail.i2p
    		"3fb8d1ee1e82981a8076ddbcbf4d18f372b8bba7",	--  privateer@mail.i2p
    		"e3815f0c985663182534fbd7d6a2bf93204a0bd0",	--  russiansponsor@mail.i2p
    		"1092773c40f5813b9179d52a8ab7b499b9554da3",	--  sponge@mail.i2p
    		"01265f0c817b24548478341fb75e672720a78b21",	--  str4d@mail.i2p
    		"38fe2aa37e1eb9a300a2061ef153265c48031c6b",	--  walking@mail.i2p
    		"a0eb78d437efad120dd9edcd776a327ec2c2adde",	--  zab@mail.i2p
    		"2158706490e62a17c8140b6e9eabca965b681bc7",	--  zab2@mail.i2p
    		"56810cd6434ab33593260e188b32bb83e4e9a139",	--  z3r0fox@mail.i2p
    		"896e399990704373125f782ae2ee19b6611ac612"	--  zzz@mail.i2p
       local t = keyintersection(signers, trusted_signers)
       if t == nil then return false end
       if #t>= 1 then return true end
       return false
  • Copy and paste the developer's commit keys into a new file (e.g. keys.txt) in the same directory that is in. Import the keys into your database with
          mtn -d read < keys.txt
  • Pull the I2P sources to your machine. This may take a long time, especially if you are doing this over I2P!
    • Anonymously: mtn -d -k "" pull "mtn://"
    • Non-anonymously: mtn -d -k "" pull "mtn://"

  • All the sources are now present on your machine, in the database file. To make them available in a directory, you need to check them out: mtn -d co --branch=i2p.i2p

    The above command creates a directory i2p.i2p, which contains all of the I2P sources.


To download the website files instead of the I2P source files, use 'i2p.www' instead of 'i2p.i2p'.

The initial pull may take several hours using the tunnel. If it fails after a partial pull, simply rerun it, it will start where it left off. If you are in a hurry, use the non-anonymous access.

A full list of branches, including i2p.i2p and i2p.www can be found on viewmtn.

A long explanation about using monotone is available on the monotone page.

Building I2P

To compile the code, you need the Sun Java Development Kit 6 or higher, or equivalent JDK (Sun JDK 6 strongly recommended) and Apache ant version 1.7.0 or higher. If you go are working on the main I2P code, you can go into the i2p.i2p directory and run 'ant' to see the build options.

To build or work on console translations, you need the xgettext, msgfmt, and msgmerge tools from the GNU gettext package.

For development on new applications, see the application development guide.

Development ideas

See zzz's TODO lists, this website's TODO list or Trac for ideas.

Making the results available

See the bottom of the licenses page for commit privilege requirements. You need these to put code into i2p.i2p (not required for the website!).

Short version of how to generate and use keys if you plan to commit:

  • mtn genkey yourname-transport@mail.i2p (use an empty passphrase)
  • mtn genkey yourname@mail.i2p (enter a passphrase)
  • mtn pubkey yourname-transport@mail.i2p (send this to a mtn repo operator to get push privileges)
  • mtn pubkey yourname@mail.i2p (send this to a release manager to get commit privileges - not required for website)
  • mtn ci -k yourname@mail.i2p (check in with this key)
  • mtn sync -k yourname-transport@mail.i2p (push with this key)
Long version: see the monotone page.

Get to know us!

The developers hang around on IRC. They can be reached on the Freenode network, OFTC, and on the I2P internal networks. The usual place to look is #i2p-dev. Join the channel and say hi! We also have additional guidelines for regular developers.


Website and router console translators: See the New Translator's Guide for next steps.


I2P is open source software that is mostly developed using open sourced toolkits. The I2P project recently acquired a license for the YourKit Java Profiler. Open source projects are eligible to receive a free license provided that YourKit is referenced on the project web site. Please get in touch if you are interested in profiling the I2P codebase.

YourKit is kindly supporting open source projects with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler.