This is what we usually do to make a library or other body of code:
write all the code
write some tests
change all the code and tests until the tests to pass on our platform
start writing documentation and examples
upload it and ask people to try it out
This approach has a couple of problems.
Coding is fun, while the ancillary tasks can be very boring, tedious and frustrating. So leaving these other tasks as an afterthought results in poor and/or incomplete documentation, testing, and concept definition.
Conceptual errors are often discovered when writing documentation, tests and concepts. Discovery of these errors usually results in changed to the code which ripple through the whole library and create a lot of work.
Poor/Incomplete documentation/testing/concepts mean that fewer conceptual errors are discovered before code is made available to users.
Users will be shipped code which is weak on documentation, tests, and examples and has conceptual errors. Often the library writer doesn't do this intentionally, it's just an effect of the way the code has been developed. Users will discover these problems, reject the library and move on. If the library writer get's any feedback it is likely to be of limited usefulness.
So reworking code and documentation after everything is "done" results in a huge amount of extra work - if the work every get's done.
The basic problem is that the ancillary tasks create a lot of useful information and this needs to be cycled back into the library code before anything is shipped. Cycling this information back sooner saves wasted time.
Here is what I recommend instead:
write a small group of classes. functions, or templates.
use concepts - what are concepts?
write documentation for this group
write and newly required concept checking classes
write a program to test this code
Repeat above for the next group.
When there is enough to be truely useful to someone, upload the package as ask people to test it. The package may not have all the features planned for it, but it should have enough functionality to be useful.
add features and make adjustments and repeat cycle above.
In contrast to the first approach.
Coding, testing, documentation, are divided into shorter tasks. So the tedium and frustration are much easier to deal with.
Information gleaned from documentation, testing, concepts, and user feedback is received sooner and saves much rework and back tracking.
The result is a higher quality library which:
Exhibits "conceptual integrity". That is, code with a clearly defined purpose which is explained in an way which makes it obvious what the code is meant to do and how to use it.
Motviates the user to take the code for a "test drive" by including the code in his own application. This should that convince the user that the library is bug free, useful, and easy to use.
Results in the user returning positive feedback and request for more features.
Motivates the library writer and perhaps other users to add features to the library.