diff --git a/ChangeLog b/ChangeLog
index 0953200c..b7fa3bb3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,8 @@
 - merge back into trunk for 7.15.1
 - remove im_ispng(), im_png2vips_header() etc. & friends
 - add "vips --list formats"
+- rename VBuf as im_buf_t for consistency
+- add type.[hc], start of new type system
 
 7/3/08 started 7.15.0
 - MAGIC constants should be tagged as unsigned
diff --git a/TODO b/TODO
index ebbf1d4d..2049445f 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,13 @@
+- do we need init functions? maybe for arrays I guess
+
+  should gvalues be inited to a specific type?
+
+  have a field in im_type_t for typeof or somesuch?
+
+  need im_object_t
+
+  should size be called sizeof
+
 - needs docs in vips manual for format stuff I guess
 
 - operations and jesper's types should all use the new register/unregister
diff --git a/libsrc/iofuncs/type.c b/libsrc/iofuncs/type.c
index 48910fb9..9b168a80 100644
--- a/libsrc/iofuncs/type.c
+++ b/libsrc/iofuncs/type.c
@@ -51,6 +51,12 @@ im_type_register( const char *name, size_t size,
 {
 	im_type_t *type;
 
+	if( im_type_lookup( name ) ) {
+		im_error( "im_type_register", 
+			_( "type name already registered" ) ); 
+		return( NULL );
+	}
+
 	if( !(type = IM_NEW( NULL, im_type_t )) )
 		return( NULL );
 
@@ -154,3 +160,22 @@ im__type_init( void )
 		0, NULL, NULL );
 }
 
+/* Allocate an im_object.
+ */
+static im_object_t *
+im_object_new( im_type_t *type, im_object_t **object )
+{
+	im_object_t *object;
+
+	if( type->size ) {
+		if( !(*object = im_malloc( NULL, type->size )) )
+			return( NULL );
+		memset( *object, 0,, type->size );
+	}
+	else
+		*object = NULL;
+
+	if( type->init )
+		type->init( object );
+}
+