web: initial implementation